From b0aa1bd6b016c6f0bc054df19a2b73c95ea27300 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Sun, 30 Mar 2014 09:03:02 +1000 Subject: Various fixes, mostly to do with stufflets, which are still slightly broken. --- ClientHamr/GuiLua/skang.lua | 49 +++++++++++++++++++++++++++++++-------------- ClientHamr/GuiLua/test.lua | 25 ++++++++++++++++++++++- 2 files changed, 58 insertions(+), 16 deletions(-) (limited to 'ClientHamr/GuiLua') diff --git a/ClientHamr/GuiLua/skang.lua b/ClientHamr/GuiLua/skang.lua index 7333e54..a742845 100644 --- a/ClientHamr/GuiLua/skang.lua +++ b/ClientHamr/GuiLua/skang.lua @@ -167,6 +167,7 @@ function printTableStart(table, space, name) end function printTable(table, space) + if nil == table then return end for k, v in pairs(table) do if type(v) == "table" then if v._NAME then @@ -334,12 +335,6 @@ Other Thing things are - quitter:action('quit') -On the other hand, might be better to now think of modules as a type? -How much of OO are we willing to go with here? lol -In Lua 5.1 and LuaJIT (?) metatables have no __type. -What about userdata? We could hijack the type() function, and dig deeper if it's a userdata, or even if it's a Thing? - - Things as a metatable field - In this plan test.__something is short for metatable(test).__something. @@ -363,8 +358,6 @@ What about userdata? We could hijack the type() function, and dig deeper if it' If module.foo is a table, it can have it's own metatable(foo). Such a table will use Thing as a proxy table via __index and __newindex, as it does now. - thing(test, 'foo', 'table' ...) -> setmetatable(thing, {__index=Thing}); thing stuff goes into thing; setmetatable(foo, thing); test.__stuff[foo] = thing; test.__values[foo] = {}; - thing(test.foo, 'bar', ...) -> setmetatable(thing, {__index=Thing}); setmetatable(foo, thing); foo.__stuff[bar] = thing; foo.__values[bar] = thing.default test.foo -> test.__index(test, 'foo') -> test.__values[foo]; if that's nil, and test.__stuff[foo], then return an empty table instead? test.foo(a) -> test.__index(test, 'foo') -> test.__values[foo](a) test.foo(a) -> test.__index(test, 'foo') -> test.__values[foo](a) (but it's not a function) -> test.__values[foo].__call(test.__values[foo], a) @@ -418,13 +411,13 @@ Thing.isValid = function (self, module) -- Check if this Thing is valid, return local key = thingy.names[1]; local value = modThing.__values[key] - local t = type(value) + local t = type(value) or 'nil' self.errors = {} -- TODO - Naturally there should be formatting functions for stuffing Thing stuff into strings, and overridable output functions. if 'nil' == t then if self.required then table.insert(self.errors, modThing.names[1] .. '.' .. name .. ' is required!') end else - if self.types[1] ~= t then table.insert(self.errors, modThing.names[1] .. '.' .. name .. ' should be a ' .. self.types[1] .. ', but it is a ' .. type(value) .. '!') + if self.types[1] ~= t then table.insert(self.errors, modThing.names[1] .. '.' .. name .. ' should be a ' .. self.types[1] .. ', but it is a ' .. t .. '!') else if 'number' == t then value = '' .. value end if ('number' == t) or ('string' == t) then @@ -432,7 +425,18 @@ Thing.isValid = function (self, module) -- Check if this Thing is valid, return end end end - -- TODO - Should go through self.__stuff[*]:isValid(self) as well. + + local stuff = getmetatable(value) + if stuff and stuff.__stuff then + for k, v in pairs(stuff.__stuff) do + if not v:isValid(value) then + for i, w in ipairs(v.errors) do + table.insert(self.errors, w) + end + end + end + end + return #(self.errors) == 0 end @@ -468,11 +472,21 @@ Thing.__newindex = function (module, key, value) local modThing = getmetatable(module) if modThing then - -- This is a proxy table, the values never exist in the real table. + -- This is a proxy table, the values never exist in the real table. In theory. local thingy = modThing.__stuff[key] if thingy then local name = thingy.names[1] - modThing.__values[name] = value + local valueMeta + if 'table' == type(value) then + -- Coz setting it via modThing screws with the __index stuff somehow. + valueMeta = getmetatable(modThing.__values[name]) + if valueMeta then + for k, v in pairs(value) do + valueMeta.__values[k] = v + end + end + end + if nil == valueMeta then modThing.__values[name] = value end if 'function' == type(value) then thingy.func = value else @@ -527,7 +541,6 @@ thing = function (names, ...) local modThing = getmetatable(module) if nil == modThing then modThing = {} - modThing.names = {module._NAME} -- This is how the Thing is stored with the module. setmetatable(module, modThing) end @@ -536,6 +549,7 @@ thing = function (names, ...) if nil == modThing.__stuff then -- Seems this does not deal with __index and __newindex, and also screws up __stuff somehow. -- setmetatable(modThing, {__index = Thing}) + modThing.names = {module._NAME or 'NoName'} modThing.__stuff = {} modThing.__values = {} modThing.__index = Thing.__index @@ -578,9 +592,14 @@ thing = function (names, ...) -- Find type, default to string, then break out the other types. local typ = type(thingy.default) if 'nil' == typ then typ = 'string' end - if types then types = typ .. ',' .. types else types = typ end + if 'function' == typ then types = typ .. ',' .. types end + if '' == types then types = typ end thingy.types = csv2table(types) + if 'table' == thingy.types[1] then + if '' == thingy.default then thingy.default = {} end + end + -- Remove old names, then stash the Thing under all of it's new names. for i, v in ipairs(oldNames) do modThing.__stuff[v] = nil diff --git a/ClientHamr/GuiLua/test.lua b/ClientHamr/GuiLua/test.lua index 73cacee..d74e22c 100644 --- a/ClientHamr/GuiLua/test.lua +++ b/ClientHamr/GuiLua/test.lua @@ -105,6 +105,7 @@ test.fooble = 42 test.fooble = true test.f = 42 test.f = nil +test.bar = 123 print('') skang.set(test, 'f', 'required', false) @@ -123,6 +124,10 @@ stuff.t = {} skang.thing{'a', module=stuff, help = 'A test stufflet'} skang.thing{'b', module=stuff.t, help = 'A sub stufflet'} skang.thing{'c', module=stuff.t, help = 'Another sub stufflet'} +skang.thing{'s', module=stuff, help = 'A Stuff', types='table'} +skang.thing{'sa', module=stuff.s, help = 'A stufflet in a Stuff'} +skang.thing{'sb', module=stuff.s, help = 'Another stufflet in a Stuff'} + print('*********************************') skang.fixNames(skang, 'skang') skang.fixNames(test, 'test') @@ -134,10 +139,14 @@ print('*********************************') print(skang.get(stuff, 'a', 'help')) print(skang.get(stuff.t, 'b', 'help')) print(skang.get(stuff.t, 'c', 'help')) +print(skang.get(stuff, 's', 'help')) +print(skang.get(stuff.s, 'sa,a', 'help')) +print(skang.get(stuff.s, 'sb,b', 'help')) skang.thing{'baz,b', module=test, help = 'A test stufflet for test'} print(skang.get(test, 'b', 'help')) print(skang.get(test, 'f', 'help')) -stuff.a = '1' +-- Should fail isValid() +stuff.a = 1 stuff.t.b = '2' stuff.t.c = '3' test.b = '422222' @@ -145,6 +154,14 @@ test.f = 5 test_c.cbar = '666' -- This one doesn't actually exist. test_c.bar = '7' +-- The sa should fail isValid() +stuff.s.sa = true +stuff.s.sb = 22 +-- TODO - This one should fail, but doesn't. It goes through to the real stuff.s table. +stuff.s.b = 33 +-- TODO - And the 'a' one just gets dropped. +stuff.s = {a=8, sb='9'} +stuff.s.sb = 44 print('') print(skang.get(stuff, 'a')) @@ -156,6 +173,9 @@ print(skang.get(test, 'f')) print(skang.get(test, 'fooble')) print(skang.get(test_c, 'cbar')) print(skang.get(test_c, 'bar')) +print(type(skang.get(stuff, 's'))) +print(skang.get(stuff.s, 'sa')) +print(skang.get(stuff.s, 'sb')) print('') print(stuff.a) @@ -169,3 +189,6 @@ print(test_c.cbar) print(test_c.bar) print(test_c.c) print(test_c.cfooble) +print(stuff.s.sa) +print(stuff.s.sb) +skang.printTableStart(stuff.s, '', 'stuff.s') -- cgit v1.1