Module:PerkSearchController: Difference between revisions

From Against the Storm Official Wiki
(Created to manage searching perks)
 
(Updated the docs)
Line 26: Line 26:


--region Private methods
--region Private methods
---
--- Takes two lists and returns the intersection of the two. Slightly more
--- efficient if the second list is smaller than the first.
---
---@param list1 table a flat table (list of values)
---@param list2 table another flat table
---@return table a similarly flat table consisting only of the values that are in both provided lists
local function findIntersection(list1, list2)
local intersection = {}
-- Create a new mapping to efficiently check for existence in list2 by
-- checking the same ID in the next loop.
local setList2 = {}
for _, value in ipairs(list2 or {}) do
setList2[value] = true
end
-- Check for intersection and populate the result table.
for _, valueToFind in ipairs(list1 or {}) do
if setList2[valueToFind] then
table.insert(intersection, valueToFind)
end
end
if #intersection == 0 then
return nil
end
return intersection
end


---
---
Line 134: Line 96:




local function buildRowsForPerks(perkList, displayOverride)
---
--- Loops through a list of IDs and filters out any that don't match the
--- specified source.
---
---@param listOfIDs table list of perk IDs
---@param source string the type of source to filter
---@return table the same list, but fewer items
local function filterAllSources(listOfIDs, source)


for _, perkID in ipairs(perkList or {}) do
-- Should never be nil at runtime.
 
if not source then
local perkName = PerksData.getNameByID(perkID)
error("Invalid parameter for source.")
local description = PerksData.getDescriptionByID(perkID)
local iconFilename = PerksData.getIconByID(perkID)
local rarity = PerksData.getRarityByID(perkID)
local price = PerksData.getPriceByID(perkID)
 
local sourceCornerstone = PerksData.isFromCornerstoneByID(perkID)
local sourceEvent = PerksData.isFromEventByID(perkID)
local sourceOrder = PerksData.isFromOrderByID(perkID)
local sourceTrader = PerksData.isFromTraderByID(perkID)
 
PerkSearchResultsView.addRowForPerk(displayOverride, perkName,
description, iconFilename, rarity, price,
sourceCornerstone, sourceEvent, sourceOrder, sourceTrader)
end
end
end
local function filterAllSources(listOfIDs, source)


-- Remove any that do not have the specified source.
-- Remove any that do not have the specified source.
Line 166: Line 117:
end
end
end
end
return listOfIDs
end
end






---
--- Loops through a list of IDs and filters out any that don't match the
--- specified rarity.
---
---@param listOfIDs table list of perk IDs
---@param rarity string a rarity constant to filter
---@return table the same list, but fewer items
local function filterAllRarities(listOfIDs, rarity)
local function filterAllRarities(listOfIDs, rarity)
-- Should never be nil at runtime.
if not rarity then
error("Invalid parameter for rarity.")
end


-- Remove any that do not have the specified rarity.
-- Remove any that do not have the specified rarity.
Line 179: Line 144:
end
end
end
end
return listOfIDs
end
end






function PerkSearchController.renderFromID(perkID, displayOverride)
---
--- Main engine converting the list of IDs into calls to the View to render
--- rows (or whatever based on list override).
---
---@param perkList table list of perk IDs
---@param displayOverride string how to display, if not default
local function buildRowsForPerks(perkList, displayOverride)
 
for _, perkID in ipairs(perkList or {}) do
 
local perkName = PerksData.getNameByID(perkID)
local description = PerksData.getDescriptionByID(perkID)
local iconFilename = PerksData.getIconByID(perkID)
local rarity = PerksData.getRarityByID(perkID)
local price = PerksData.getPriceByID(perkID)
 
local sourceCornerstone = PerksData.isFromCornerstoneByID(perkID)
local sourceEvent = PerksData.isFromEventByID(perkID)
local sourceOrder = PerksData.isFromOrderByID(perkID)
local sourceTrader = PerksData.isFromTraderByID(perkID)
 
PerkSearchResultsView.addRowForPerk(displayOverride, perkName,
description, iconFilename, rarity, price,
sourceCornerstone, sourceEvent, sourceOrder, sourceTrader)
end
end
 
 
 
---
--- Organizes a list of IDs to send to the build method. Calls the View's
--- setup, builds, and end.
---
---@param perkID string a single perk's ID
---@param displayOverride string how to display, if not default
local function renderFromID(perkID, displayOverride)


local perkName = PerksData.getNameByID(perkID)
local perkName = PerksData.getNameByID(perkID)
Line 202: Line 204:




function PerkSearchController.renderFromName(name, displayOverride)
---
--- Organizes a list of IDs to send to the build method. Calls the View's
--- setup, builds, and end.
---
---@param perkName string the name of a Perk
---@param displayOverride string how to display, if not default
local function renderFromName(perkName, displayOverride)


local perkIDsList = PerksData.getAllPerkIDsByName(name)
local perkIDsList = PerksData.getAllPerkIDsByName(perkName)


if not perkIDsList or #perkIDsList == 0 then
if not perkIDsList or #perkIDsList == 0 then
return "No perk found with name " .. name .. "."
return "No perk found with name " .. perkName .. "."
end
end


Line 213: Line 221:
local isFromTrader = isAnyFromTrader(perkIDsList)
local isFromTrader = isAnyFromTrader(perkIDsList)


PerkSearchResultsView.startViewForName(name, displayOverride, numPerks, isFromTrader)
PerkSearchResultsView.startViewForName(perkName, displayOverride, numPerks, isFromTrader)


buildRowsForPerks(perkIDsList, displayOverride)
buildRowsForPerks(perkIDsList, displayOverride)
Line 222: Line 230:




function PerkSearchController.renderSearch(searchTerm, source, rarity, displayOverride)
---
--- Organizes a list of IDs to send to the build method. Calls the View's
--- setup, builds, and end.
---
---@param searchTerm string the text to search from all perks
---@param source string the type of source to filter, if any
---@param rarity string a rarity constant to filter, if any
---@param displayOverride string how to display, if not default
---@return table
local function renderSearch(searchTerm, source, rarity, displayOverride)


local starterList = searchAllNamesAndDescriptions(searchTerm)
local starterList = searchAllNamesAndDescriptions(searchTerm)
Line 254: Line 271:
--region Public methods
--region Public methods


function PerkSearchController.searchResults(frame)
---
--- Main method invoked from the template.
---
---@param frame table the MediaWiki calling context
---@return string long wiki markup with the results
function PerkSearchController.search(frame)


-- Extract the template parameters.
-- Extract the template parameters.
Line 265: Line 287:


if id and id ~= "" then
if id and id ~= "" then
return PerkSearchController.renderFromID(perkID, displayOverride)
return renderFromID(perkID, displayOverride)
else
else
if name and name ~= "" then
if name and name ~= "" then
return PerkSearchController.renderFromName(name, displayOverride)
return renderFromName(name, displayOverride)
else
else
if searchTerm and searchTerm ~= "" then
if searchTerm and searchTerm ~= "" then
return PerkSearchController.renderSearch(searchTerm, source, rarity, displayOverride)
return renderSearch(searchTerm, source, rarity, displayOverride)
else
else
return "Unknown parameter in Perk Search template."
return "Unknown parameter in Perk Search template."

Revision as of 15:19, 3 December 2023

Documentation for this module may be created at Module:PerkSearchController/doc

---
--- Module for searching data on perks and displaying results
---
--- @module PerkSearchController
local PerkSearchController = {}



local PerkSearchResultsView = require("Module:PerkSearchResultsView")

local PerksData = require("Module:PerksData")



--region Private member variables

--endregion



--region Private constants

--endregion



--region Private methods

---
--- Takes two lists and returns the union of the two.
---
---@param list1 table a flat table (list of values)
---@param list2 table another flat table
---@return table a similarly flat table consisting of the values of both lists
local function findUnion(list1, list2)

	local union = {}

	for _, value in ipairs(list2) do
		table.insert(union, value)
	end

	-- Have to check before adding them to not add duplicates.
	for _, value in ipairs(list1) do
		for _, alreadyValue in ipairs(list2) do
			if value ~= alreadyValue then
				table.insert(union, value)
			end
		end
	end

	return union
end



---
--- Runs through the provided list of IDs and returns true if any are from
--- a Trader.
---
---@param perkIDsList table list of perkIDs
---@return boolean whether any in the list are from a Trader
local function isAnyFromTrader(perkIDsList)

	-- Should never be nil at runtime.
	if not perkIDsList then
		error("Invalid list of perk IDs.")
	end

	for _, perkID in ipairs(perkIDsList) do

		if PerksData.isFromTraderByID(perkID) then
			return true
		end
	end

	return false
end



---
--- Searches through perks for matches in descriptions and names and returns
--- the results of both merged into one list.
---
---@param searchTerm string the terms to search for
---@return table a list of perk IDs that match
local function searchAllNamesAndDescriptions(searchTerm)

	local listFromSearchingNames = PerksData.getAllPerkIDsWhereName(searchTerm)
	local listFromSearchingDescriptions = PerksData.getAllPerkIDsWhereDescription(searchTerm)

	return findUnion(listFromSearchingDescriptions, listFromSearchingNames)
end



---
--- Loops through a list of IDs and filters out any that don't match the
--- specified source.
---
---@param listOfIDs table list of perk IDs
---@param source string the type of source to filter
---@return table the same list, but fewer items
local function filterAllSources(listOfIDs, source)

	-- Should never be nil at runtime.
	if not source then
		error("Invalid parameter for source.")
	end

	-- Remove any that do not have the specified source.
	for i, perkID in pairs(listOfIDs) do

		if not PerksData.isAnySource(perkID, source) then
			listOfIDs[i] = nil
		end
	end

	return listOfIDs
end



---
--- Loops through a list of IDs and filters out any that don't match the
--- specified rarity.
---
---@param listOfIDs table list of perk IDs
---@param rarity string a rarity constant to filter
---@return table the same list, but fewer items
local function filterAllRarities(listOfIDs, rarity)

	-- Should never be nil at runtime.
	if not rarity then
		error("Invalid parameter for rarity.")
	end

	-- Remove any that do not have the specified rarity.
	for i, perkID in pairs(listOfIDs) do

		if not PerksData.isRarityMatchByID(perkID, rarity) then
			listOfIDs[i] = nil
		end
	end

	return listOfIDs
end



---
--- Main engine converting the list of IDs into calls to the View to render
--- rows (or whatever based on list override).
---
---@param perkList table list of perk IDs
---@param displayOverride string how to display, if not default
local function buildRowsForPerks(perkList, displayOverride)

	for _, perkID in ipairs(perkList or {}) do

		local perkName = PerksData.getNameByID(perkID)
		local description = PerksData.getDescriptionByID(perkID)
		local iconFilename = PerksData.getIconByID(perkID)
		local rarity = PerksData.getRarityByID(perkID)
		local price = PerksData.getPriceByID(perkID)

		local sourceCornerstone = PerksData.isFromCornerstoneByID(perkID)
		local sourceEvent = PerksData.isFromEventByID(perkID)
		local sourceOrder = PerksData.isFromOrderByID(perkID)
		local sourceTrader = PerksData.isFromTraderByID(perkID)

		PerkSearchResultsView.addRowForPerk(displayOverride, perkName,
				description, iconFilename, rarity, price,
				sourceCornerstone, sourceEvent, sourceOrder, sourceTrader)
	end
end



---
--- Organizes a list of IDs to send to the build method. Calls the View's
--- setup, builds, and end.
---
---@param perkID string a single perk's ID
---@param displayOverride string how to display, if not default
local function renderFromID(perkID, displayOverride)

	local perkName = PerksData.getNameByID(perkID)

	if not perkName then
		return "No perk found with ID " .. perkID .. "."
	end

	local isFromTrader = PerksData.isFromTraderByID(perkID)

	PerkSearchResultsView.startViewForPerk(perkName, displayOverride, isFromTrader)

	buildRowsForPerks( { perkID }, displayOverride )

	return PerkSearchResultsView.endView(displayOverride)
end



---
--- Organizes a list of IDs to send to the build method. Calls the View's
--- setup, builds, and end.
---
---@param perkName string the name of a Perk
---@param displayOverride string how to display, if not default
local function renderFromName(perkName, displayOverride)

	local perkIDsList = PerksData.getAllPerkIDsByName(perkName)

	if not perkIDsList or #perkIDsList == 0 then
		return "No perk found with name " .. perkName .. "."
	end

	local numPerks = #perkIDsList
	local isFromTrader = isAnyFromTrader(perkIDsList)

	PerkSearchResultsView.startViewForName(perkName, displayOverride, numPerks, isFromTrader)

	buildRowsForPerks(perkIDsList, displayOverride)

	return PerkSearchResultsView.endView(displayOverride)
end



---
--- Organizes a list of IDs to send to the build method. Calls the View's
--- setup, builds, and end.
---
---@param searchTerm string the text to search from all perks
---@param source string the type of source to filter, if any
---@param rarity string a rarity constant to filter, if any
---@param displayOverride string how to display, if not default
---@return table
local function renderSearch(searchTerm, source, rarity, displayOverride)

	local starterList = searchAllNamesAndDescriptions(searchTerm)

	local filteredList = starterList
	if source ~= nil then
		filteredList = filterAllSources(filteredList, source)
	end
	if rarity ~= nil then
		filteredList = filterAllRarities(filteredList, rarity)
	end

	if not filteredList or #filteredList == 0 then
		return "No perk found with specified search criteria."
	end

	local numPerks = #perkIDsList
	local isFromTrader = isAnyFromTrader(perkIDsList)

	PerkSearchResultsView.startViewForSearchResults(searchTerm, source, rarity, displayOverride, numPerks, isFromTrader)

	buildRowsForPerks(filteredList, displayOverride)

	return PerkSearchResultsView.endView(displayOverride)
end

--endregion



--region Public methods

---
--- Main method invoked from the template.
---
---@param frame table the MediaWiki calling context
---@return string long wiki markup with the results
function PerkSearchController.search(frame)

	-- Extract the template parameters.
	local perkID = frame.args.id or frame.args[1]
	local name = frame.args.name
	local searchTerm = frame.args.search
	local source = frame.args.source
	local rarity = frame.args.rarity
	local displayOverride = frame.args.display

	if id and id ~= "" then
		return renderFromID(perkID, displayOverride)
	else
		if name and name ~= "" then
			return renderFromName(name, displayOverride)
		else
			if searchTerm and searchTerm ~= "" then
				return renderSearch(searchTerm, source, rarity, displayOverride)
			else
				return "Unknown parameter in Perk Search template."
			end
		end
	end
end

--endregion

return PerkSearchController