(Functional again, refactoring still in progress) Tag: sourceedit |
(still a work in progress. I've determined that it would be best if I revised the structure of the data modules. Ideally merge all subtables back into the main one.) Tag: sourceedit |
||
Line 112: | Line 112: | ||
end |
end |
||
} |
} |
||
+ | |||
local objectMeta = { |
local objectMeta = { |
||
__index = function(o,k) |
__index = function(o,k) |
||
local class = o._classDefinition; |
local class = o._classDefinition; |
||
+ | if k == "_objectManager" then |
||
+ | o[k] = require(class.ObjectsPath ); |
||
⚫ | |||
⚫ | |||
for i = 1, #class.StringFields do |
for i = 1, #class.StringFields do |
||
if k == class.StringFields[i] then |
if k == class.StringFields[i] then |
||
Line 136: | Line 141: | ||
for fieldName,className in pairs(class.ObjectFields) do |
for fieldName,className in pairs(class.ObjectFields) do |
||
if k == fieldName then |
if k == fieldName then |
||
− | o[k] |
+ | local id = o._objectFields[k]; |
− | + | if id then |
|
+ | o[k] = o._objectManager.CreateObject(id,className); |
||
⚫ | |||
− | + | return o[k]; |
|
+ | else |
||
⚫ | |||
− | + | return nil; |
|
− | + | end |
|
⚫ | |||
end |
end |
||
end |
end |
||
Line 155: | Line 159: | ||
local ObjectClassDefinition = {ClassName = "Object"}; |
local ObjectClassDefinition = {ClassName = "Object"}; |
||
− | function |
+ | function CreateObjectList(classDefinition) |
classDefinition = classDefinition or ObjectClassDefinition; |
classDefinition = classDefinition or ObjectClassDefinition; |
||
− | local |
+ | local ol = setmetatable( |
− | + | {SortByField = SortByField, |
|
Sort = SortByField, |
Sort = SortByField, |
||
SortById = SortById, |
SortById = SortById, |
||
SortByName = SortByName, |
SortByName = SortByName, |
||
− | GetByField =GetByField, |
+ | GetByField = GetByField, |
GetById = GetById, |
GetById = GetById, |
||
GetByName = GetByName, |
GetByName = GetByName, |
||
Line 170: | Line 174: | ||
Select = SelectField, |
Select = SelectField, |
||
ToString = ToString},objectListMeta); |
ToString = ToString},objectListMeta); |
||
− | + | ol._classDefinition = classDefinition; |
|
− | return classDefinition.ObjectListConstructor and classDefinition.ObjectListConstructor( |
+ | return classDefinition.ObjectListConstructor and classDefinition.ObjectListConstructor(ol) or ol; |
end |
end |
||
+ | local function UnindexObjectFields(o) |
||
⚫ | |||
+ | o._objectFields = {}; |
||
+ | for key,value in pairs(o) do |
||
⚫ | |||
+ | if key == fieldName then |
||
+ | o._objectFields[key] = value; |
||
+ | o[key] = nil; |
||
+ | end |
||
+ | end |
||
⚫ | |||
+ | end |
||
+ | |||
⚫ | |||
classDefinition = classDefinition or ObjectClassDefinition; |
classDefinition = classDefinition or ObjectClassDefinition; |
||
− | local |
+ | local o = utils.RecreateTable(value); |
− | + | o.Id = id; |
|
− | + | o._classDefinition = classDefinition or ObjectClassDefinition; |
|
+ | UnindexObjectFields(o) |
||
− | + | o = setmetatable(o,objectMeta); |
|
− | return classDefinition.ObjectConstructor and classDefinition.ObjectConstructor( |
+ | return classDefinition.ObjectConstructor and classDefinition.ObjectConstructor(o) or o; |
end |
end |
||
− | + | function FillObjectList(ol,data,classDefinition) |
|
for k,v in pairs(data) do |
for k,v in pairs(data) do |
||
− | local o = |
+ | local o = CreateObject(k,v,classDefinition); |
if classDefinition.ObjectListInitialFilter then |
if classDefinition.ObjectListInitialFilter then |
||
if classDefinition.ObjectListInitialFilter(o) then |
if classDefinition.ObjectListInitialFilter(o) then |
||
Line 197: | Line 214: | ||
end |
end |
||
+ | function DEBUG() |
||
− | local ObjectsManager = {}; |
||
+ | local data = require("Module:Data/Civ6/Base") |
||
− | |||
+ | local cd = require("Module:Data/Civ6/Base/Objects/Buildings"); |
||
− | function ObjectsManager.CreateObject(id,value,classDefinition) |
||
+ | local ol = CreateObjectList(cd); |
||
− | return _createObject(id,value,classDefinition) |
||
+ | FillObjectList(ol,data.Buildings,cd) |
||
⚫ | |||
+ | return ol; |
||
− | |||
− | function ObjectsManager.CreateObjectList(data,classDefinition) |
||
− | local ol = _createObjectList(classDefinition) |
||
− | return _fillObjectList(ol,data,classDefinition); |
||
end |
end |
||
+ | return {CreateObject = CreateObject, |
||
− | return ObjectsManager; |
||
+ | CreateObjectList = CreateObjectList, |
||
+ | FillObjectList = FillObjectList, |
||
+ | DEBUG = DEBUG}; |
Revision as of 23:06, 28 October 2016
Documentation for this module may be created at Module:Data/Objects/doc
local utils = require("Module:TemplateUtils");
local function GetByField(self,field,value)
for i = 1, #self do
if self[i][field] and self[i][field] == value then
return self[i]
end
end
end
local function GetById(self, id)
return GetByField(self,"Id",id)
end
local function GetByName(self, name)
return GetByField(self,"Name",name)
end
local function SortByField(self,field,desc)
if desc then
table.sort(self,function(a,b)
return ( a[field] > b[field] )
end)
else
table.sort(self,function(a,b)
return ( a[field] < b[field] )
end)
end
return self
end
local function SortById(self,desc)
return SortByField(self,"Id",desc)
end
local function SortByName(self,desc)
return SortByField(self,"Name",desc)
end
local comparators = {
eq = function(a,b) return a == b end,
neq = function(a,b) return not (a == b) end,
lt = function(a,b) return a < b end,
gt = function(a,b) return a > b end,
lteq = function(a,b) return a <= b end,
gteq = function(a,b) return a >= b end}
local function _selectComparator(c)
if c == "eq" or c == "Equal" then return comparators.eq end;
if c == "neq" or c == "NotEqual" then return comparators.neq end;
if c == "lt" or c == "LessThan" then return comparators.lt end;
if c == "gt" or c == "GreaterThan" then return comparators.gt end;
if c == "lteq" or c == "LessThanOrEqual" then return comparators.lteq end;
if c == "gteq" or c == "GreaterThanOrEqual" then return comparators.gteq end;
return comparators.eq; -- Default
end
local function FilterByField(self,field,value,comparator)
comparator = _selectComparator(comparator) or comparators.eq
local t = _createObjectList(self._classDefinition)
for i = 1, #self do
if comparator(self[i][field],value) then
table.insert(t,self[i])
end
end
return t;
end
local function SelectField(self,field)
local t = _createObjectList(self._classDefinition)
for i = 1, #self do
if self[i][field] then
table.insert(t,self[i][field])
end
end
return t;
end
local function ToString(self,field,separator)
separator = separator or ", "
local strings = {}
for i = 1, #self do
if field then
if self[i][field] then
table.insert(strings,tostring(self[i][field]))
end
else
table.insert(strings,tostring(self[i]))
end
end
return table.concat(strings,separator)
end
--ObjectList metatable
local objectListMeta = {
--Alternative accessor by Id or Name
__index=function(o,k)
for i = 1, #o do
if o[i].Id and o[i].Id == k then
return o[i]
end
end
for i = 1, #o do
if o[i].Name and o[i].Name == k then
return o[i]
end
end
end,
__tostring = function(o)
return "{"..o._classDefinition.ClassName.."List"..":Count="..#o.."}"
end
}
local objectMeta = {
__index = function(o,k)
local class = o._classDefinition;
if k == "_objectManager" then
o[k] = require(class.ObjectsPath );
return o[k];
end
for i = 1, #class.StringFields do
if k == class.StringFields[i] then
o[k] = "";
return o[k];
end
end
for i = 1, #class.BooleanFields do
if k == class.BooleanFields[i] then
o[k] = false;
return o[k];
end
end
for i = 1, #class.NumberFields do
if k == class.NumberFields[i] then
o[k] = 0;
return o[k];
end
end
for fieldName,className in pairs(class.ObjectFields) do
if k == fieldName then
local id = o._objectFields[k];
if id then
o[k] = o._objectManager.CreateObject(id,className);
return o[k];
else
return nil;
end
end
end
end,
__tostring = function(o)
return "{"..o._classDefinition.ClassName..":"..(o.Id).."}"
end
}
--Generic class definition when no other is available
local ObjectClassDefinition = {ClassName = "Object"};
function CreateObjectList(classDefinition)
classDefinition = classDefinition or ObjectClassDefinition;
local ol = setmetatable(
{SortByField = SortByField,
Sort = SortByField,
SortById = SortById,
SortByName = SortByName,
GetByField = GetByField,
GetById = GetById,
GetByName = GetByName,
FilterByField = FilterByField,
Filter = FilterByField,
SelectField = SelectField,
Select = SelectField,
ToString = ToString},objectListMeta);
ol._classDefinition = classDefinition;
return classDefinition.ObjectListConstructor and classDefinition.ObjectListConstructor(ol) or ol;
end
local function UnindexObjectFields(o)
o._objectFields = {};
for key,value in pairs(o) do
for fieldName,_ in pairs(o._classDefinition.ObjectFields) do
if key == fieldName then
o._objectFields[key] = value;
o[key] = nil;
end
end
end
end
function CreateObject(id,value,classDefinition)
classDefinition = classDefinition or ObjectClassDefinition;
local o = utils.RecreateTable(value);
o.Id = id;
o._classDefinition = classDefinition or ObjectClassDefinition;
UnindexObjectFields(o)
o = setmetatable(o,objectMeta);
return classDefinition.ObjectConstructor and classDefinition.ObjectConstructor(o) or o;
end
function FillObjectList(ol,data,classDefinition)
for k,v in pairs(data) do
local o = CreateObject(k,v,classDefinition);
if classDefinition.ObjectListInitialFilter then
if classDefinition.ObjectListInitialFilter(o) then
table.insert(ol,o);
end
else
table.insert(ol,o);
end
end
return ol;
end
function DEBUG()
local data = require("Module:Data/Civ6/Base")
local cd = require("Module:Data/Civ6/Base/Objects/Buildings");
local ol = CreateObjectList(cd);
FillObjectList(ol,data.Buildings,cd)
return ol;
end
return {CreateObject = CreateObject,
CreateObjectList = CreateObjectList,
FillObjectList = FillObjectList,
DEBUG = DEBUG};