Module:PerkSearchController: Difference between revisions

From Against the Storm Official Wiki
(Created to manage searching perks)
 
(changed filtering to make new list instead of edit parameter)
 
(6 intermediate revisions by the same user not shown)
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 73: Line 35:
local function findUnion(list1, list2)
local function findUnion(list1, list2)


local union = {}
local unionList = {}


-- Have to check before adding them to not add duplicates.
local checkList = {}
for _, value in ipairs(list2) do
for _, value in ipairs(list2) do
table.insert(union, value)
table.insert(unionList, value)
checkList[value] = true
end
end


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


return union
return unionList
end
end


Line 134: Line 98:




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
error("Invalid parameter for source.")
end


local perkName = PerksData.getNameByID(perkID)
local newList = {}
local description = PerksData.getDescriptionByID(perkID)
-- Remove any that do not have the specified source.
local iconFilename = PerksData.getIconByID(perkID)
for _, perkID in ipairs(listOfIDs) do
local rarity = PerksData.getRarityByID(perkID)
local price = PerksData.getPriceByID(perkID)


local sourceCornerstone = PerksData.isFromCornerstoneByID(perkID)
if PerksData.isAnySource(perkID, source) then
local sourceEvent = PerksData.isFromEventByID(perkID)
table.insert(newList, perkID)
local sourceOrder = PerksData.isFromOrderByID(perkID)
end
local sourceTrader = PerksData.isFromTraderByID(perkID)
end


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






local function filterAllSources(listOfIDs, source)
---
--- 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 source.
local newList = {}
for i, perkID in pairs(listOfIDs) do
-- Remove any that do not have the specified rarity.
for _, perkID in ipairs(listOfIDs) do


if not PerksData.isAnySource(perkID, source) then
if PerksData.isRarityMatchByID(perkID, rarity) then
listOfIDs[i] = nil
table.insert(newList, perkID)
end
end
end
end
return newList
end
end






local function filterAllRarities(listOfIDs, rarity)
---
--- 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
---@param hasLastColumn boolean whether to write the last column
local function buildRowsForPerks(perkList, displayOverride, hasLastColumn)
 
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)


-- Remove any that do not have the specified rarity.
local sourceCornerstone = PerksData.isFromCornerstoneByID(perkID)
for i, perkID in pairs(listOfIDs) do
local sourceEvent = PerksData.isFromEventByID(perkID)
local sourceOrder = PerksData.isFromOrderByID(perkID)
local sourceTrader = PerksData.isFromTraderByID(perkID)


if not PerksData.isRarityMatchByID(perkID, rarity) then
PerkSearchResultsView.addRowForPerk(displayOverride, perkName,
listOfIDs[i] = nil
description, iconFilename, rarity, price,
end
sourceCornerstone, sourceEvent, sourceOrder, sourceTrader, hasLastColumn)
end
end
end
end
Line 183: Line 184:




function PerkSearchController.renderFromID(perkID, displayOverride)
---
--- 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 195: Line 202:
PerkSearchResultsView.startViewForPerk(perkName, displayOverride, isFromTrader)
PerkSearchResultsView.startViewForPerk(perkName, displayOverride, isFromTrader)


buildRowsForPerks( { perkID }, displayOverride )
buildRowsForPerks( { perkID }, displayOverride, isFromTrader)


return PerkSearchResultsView.endView(displayOverride)
return PerkSearchResultsView.endView(displayOverride)
Line 202: Line 209:




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 226:
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, isFromTrader)


return PerkSearchResultsView.endView(displayOverride)
return PerkSearchResultsView.endView(displayOverride)
Line 222: Line 235:




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 238: Line 260:
end
end


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


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


buildRowsForPerks(filteredList, displayOverride)
buildRowsForPerks(filteredList, displayOverride, isFromTrader)


return PerkSearchResultsView.endView(displayOverride)
return PerkSearchResultsView.endView(displayOverride)
Line 254: Line 276:
--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 264: Line 291:
local displayOverride = frame.args.display
local displayOverride = frame.args.display


if id and id ~= "" then
-- Convert empty strings on these only to nil
return PerkSearchController.renderFromID(perkID, displayOverride)
if source == "" then
source = nil
end
if rarity == "" then
rarity = nil
end
 
if perkID and perkID ~= "" then
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."

Latest revision as of 03:33, 4 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 unionList = {}

	-- Have to check before adding them to not add duplicates.
	local checkList = {}
	for _, value in ipairs(list2) do
		table.insert(unionList, value)
		checkList[value] = true
	end


	for _, value in ipairs(list1) do
		if not checkList[value] then
			table.insert(unionList, value)
			checkList[value] = true
		end
	end

	return unionList
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

	local newList = {}
	-- Remove any that do not have the specified source.
	for _, perkID in ipairs(listOfIDs) do

		if PerksData.isAnySource(perkID, source) then
			table.insert(newList, perkID)
		end
	end

	return newList
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

	local newList = {}
	-- Remove any that do not have the specified rarity.
	for _, perkID in ipairs(listOfIDs) do

		if PerksData.isRarityMatchByID(perkID, rarity) then
			table.insert(newList, perkID)
		end
	end

	return newList
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
---@param hasLastColumn boolean whether to write the last column
local function buildRowsForPerks(perkList, displayOverride, hasLastColumn)

	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, hasLastColumn)
	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, isFromTrader)

	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, isFromTrader)

	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 = #filteredList
	local isFromTrader = isAnyFromTrader(filteredList)

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

	buildRowsForPerks(filteredList, displayOverride, isFromTrader)

	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

	-- Convert empty strings on these only to nil
	if source == "" then
		source = nil
	end
	if rarity == "" then
		rarity = nil
	end

	if perkID and perkID ~= "" 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