aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ClientHamr/GuiLua/skang.lua289
-rw-r--r--ClientHamr/GuiLua/test.lua36
2 files changed, 163 insertions, 162 deletions
diff --git a/ClientHamr/GuiLua/skang.lua b/ClientHamr/GuiLua/skang.lua
index 3baad4f..9efd03c 100644
--- a/ClientHamr/GuiLua/skang.lua
+++ b/ClientHamr/GuiLua/skang.lua
@@ -57,8 +57,7 @@ The old skang argument types are -
57do -- Only I'm not gonna indent this. 57do -- Only I'm not gonna indent this.
58 58
59 59
60-- There is no ThingSpace, now it's all just in this table, and meta table. Predefined here coz moduleBegin references Thing. 60-- There is no ThingSpace, or Stuff, now it's all just in this meta table. Predefined here coz moduleBegin references Thing.
61things = {}
62Thing = {} 61Thing = {}
63 62
64 63
@@ -124,13 +123,10 @@ moduleBegin = function (name, author, copyright, version, timestamp, skin, isLua
124 -- TODO - If there's no skin passed in, try to find the file skin .. '.skang' and load that instead. 123 -- TODO - If there's no skin passed in, try to find the file skin .. '.skang' and load that instead.
125 _M.DEFAULT_SKANG = skin 124 _M.DEFAULT_SKANG = skin
126 125
127
128 --_G[_M._NAME] = _M -- Stuff it into a global of the same name. 126 --_G[_M._NAME] = _M -- Stuff it into a global of the same name.
129 -- Not such a good idea to stomp on global name space. 127 -- Not such a good idea to stomp on global name space.
130 -- It's also redundant coz we get stored in package.loaded[_M._NAME] anyway. 128 -- It's also redundant coz we get stored in package.loaded[_M._NAME] anyway.
131 -- This is why module() is broken. 129 -- This is why module() is broken.
132
133 setmetatable(_M, Thing)
134 _M.savedEnvironment = savedEnvironment 130 _M.savedEnvironment = savedEnvironment
135 -- NOTE - setfenv() wont work if the environment it refers to is a C function. Worse, getfenv() returns the global environment, so we can't tell. 131 -- NOTE - setfenv() wont work if the environment it refers to is a C function. Worse, getfenv() returns the global environment, so we can't tell.
136 if isLua then 132 if isLua then
@@ -142,6 +138,10 @@ moduleBegin = function (name, author, copyright, version, timestamp, skin, isLua
142 -- Next question, does this screw with the environment of the skang module? No it doesn't, coz that's set up at require 'skang' time. 138 -- Next question, does this screw with the environment of the skang module? No it doesn't, coz that's set up at require 'skang' time.
143 end 139 end
144 140
141 local thing = {}
142 thing.names = {name}
143 setmetatable(_M, thing)
144
145 print('Loaded module ' .. _M._NAME .. ' version ' .. _M.VERSION .. ', ' .. _M.COPYRIGHT .. '.\n ' .. _M.VERSION_DESC) 145 print('Loaded module ' .. _M._NAME .. ' version ' .. _M.VERSION .. ', ' .. _M.COPYRIGHT .. '.\n ' .. _M.VERSION_DESC)
146 146
147 return _M 147 return _M
@@ -288,91 +288,6 @@ Other Thing things are -
288--[[ TODO 288--[[ TODO
289 NOTE that skang.thing{} doesn't care what other names you pass in, they all get assigned to the thing. 289 NOTE that skang.thing{} doesn't care what other names you pass in, they all get assigned to the thing.
290 290
291Might be better to move skang.things.foo.value -> skang.values.module.foo
292but keep skang.things.foo.* for the Thing metadata.
293
294 test.pre
295 skang.things.test
296 skang.things.test.foo
297 skang.things.pre_test.foo -> skang.things.test.foo
298 skang.values.test.foo
299 skang.values.pre_test.foo
300
301 thing:isValid(module)
302 skang.things[module][key]:isValid(module)
303 skang.things.test.foo:isValid(test)
304 isValid(thing, module)
305 local value = values[module._NAME][self.names[1] ]
306
307 __index(module, key)
308 local thing = things[module._NAME][key]
309 local value = values[module._NAME][key]
310
311 __newindex(module, key, value)
312 local thing = things[module._NAME][key]
313 local oldValue = values[module._NAME][key]
314 ...
315 values[module._NAME][key] = value
316 ...
317 if not thing:isValid(module) then
318
319 module(...) or module{...}
320 __call(module, ...)
321
322 new = function (module, name)
323 local result = {}
324 setmetatable(result, {__index=module})
325 result._NAME = name
326 -- Loop through the Things in module.
327 for k, v in pairs(module.things) do
328 values[name][k] = values[module._NAME][k]
329 end
330
331On the other hand, might be better to now think of modules as a type?
332How much of OO are we willing to go with here? lol
333In Lua 5.1 and LuaJIT (?) metatables have no __type.
334What about userdata? We could hijack the type() function, and dig deeper if it's a userdata, or even if it's a Thing?
335
336
337 Things as a metatable field -
338 In this plan test.__something is short for metatable(test).__something.
339
340 C can set metatables to non table values. NOTE - values, not variables, so likely useless.
341
342 __index is used to look up things that don't exist in a table.
343 If table isn't actually a table, then use __index as well.
344 Actually, in that case, the environment is the "table".
345 Either way, if we get to __index, and it's a function, call the function.
346 If __index is not a function, then use __index as a table to start the lookup all over again.
347
348 __newindex is similar, it's used if table.key is nil, AND __newindex exists.
349 Otherwise, it just sets table.key.
350 Again, if __newindow is a table, then start the lookup all over again with that.
351
352 metatable(module).__thing
353 metatable(module).__stuff
354 metatable(module).__values
355
356 __thing is a table that is a Thing. It can be just a reference to a __thing elsewhere.
357 So module is free to be full of random variables that are anything.
358 If module.foo is a table, it can have it's own metatable(foo).__thing.
359 A table with __thing will use Thing as a proxy table via __index and __newindex, as it does now.
360
361 moduleBegin(test, ...) -> thing stuff goes into test.__thing
362 thing(test, 'foo', 'string' ...) -> thing stuff gous into thing; setmetatable(test, Thing); test.__stuff[foo] = thing; test.__values[foo] = default
363 thing(test, 'foo', 'table' ...) -> thing stuff goes into thing; setmetatable(foo, Thing); test.__stuff[foo] = thing; test.__values[foo] = {}; test.foo.__thing = thing
364 thing(test.foo, 'bar', ...) -> setmetatable(foo, Thing); foo.__stuff[bar] = thing; foo.__values[bar] = default
365 copy(test, 'c' -> c.__thing = test.__thing;, c.__stuff = test.__stuff; copy test.__values to c.__values; setmetatable(c, Thing)
366 test.foo -> test.__index(test, 'foo') -> test.__values[foo]; if that's nil, and test.__stuff[foo].__thing, then return an empty table instead?
367 test.foo = v -> test.__newindex(test, 'foo', v) -> test.__values[foo] = v; test.__stuff[foo]:isValid(test) -> local value = test.__values[ self.names[1] ]
368 Which should call self.__stuff[*]:isValid(self)
369 test.foo(a) -> test.__index(test, 'foo') -> test.__values[foo](a)
370 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)
371 Doesn't seem useful.
372 If test.foo is a table, with a __thing then that might be -> test.foo.__call(test.foo, a) -> could do something useful with this.
373 get(test.foo, 'help') -> return test.foo.__thing[help]
374 skang.thing{test, 'foo', required=true} -> test.__stuff[foo].required = true
375
376 291
377 Stuff - 292 Stuff -
378 test{'foo', key='blah', field0='something', field1=1, ...} -> skang.things.foo.key='blah' skang.things.foo.field='something' ... 293 test{'foo', key='blah', field0='something', field1=1, ...} -> skang.things.foo.key='blah' skang.things.foo.field='something' ...
@@ -417,8 +332,48 @@ What about userdata? We could hijack the type() function, and dig deeper if it'
417 -- If we had linked to this theoretical 'quit' Thing, then pushing that Quit button would invoke it's Thing function. 332 -- If we had linked to this theoretical 'quit' Thing, then pushing that Quit button would invoke it's Thing function.
418 quitter = skang.widget(nil, 'button', 'Quit', 0.5, 0.5, 0.5, 0.5) 333 quitter = skang.widget(nil, 'button', 'Quit', 0.5, 0.5, 0.5, 0.5)
419 quitter:action('quit') 334 quitter:action('quit')
335
336
337On the other hand, might be better to now think of modules as a type?
338How much of OO are we willing to go with here? lol
339In Lua 5.1 and LuaJIT (?) metatables have no __type.
340What about userdata? We could hijack the type() function, and dig deeper if it's a userdata, or even if it's a Thing?
341
342
343 Things as a metatable field -
344 In this plan test.__something is short for metatable(test).__something.
345
346 C can set metatables to non table values. NOTE - values, not variables, so likely useless.
347
348 __index is used to look up things that don't exist in a table.
349 If table isn't actually a table, then use __index as well.
350 Actually, in that case, the environment is the "table".
351 Either way, if we get to __index, and it's a function, call the function.
352 If __index is not a function, then use __index as a table to start the lookup all over again.
353
354 __newindex is similar, it's used if table.key is nil, AND __newindex exists.
355 Otherwise, it just sets table.key.
356 Again, if __newindow is a table, then start the lookup all over again with that.
357
358 metatable(module).__stuff
359 metatable(module).__values
360
361 The Thing is stuffed in a metatable. It can be just a reference to an existing Thing elsewhere.
362 So module is free to be full of random variables that are anything.
363 If module.foo is a table, it can have it's own metatable(foo).
364 Such a table will use Thing as a proxy table via __index and __newindex, as it does now.
365
366 thing(test, 'foo', 'table' ...) -> setmetatable(thing, {__index=Thing}); thing stuff goes into thing; setmetatable(foo, thing); test.__stuff[foo] = thing; test.__values[foo] = {};
367 thing(test.foo, 'bar', ...) -> setmetatable(thing, {__index=Thing}); setmetatable(foo, thing); foo.__stuff[bar] = thing; foo.__values[bar] = thing.default
368 test.foo -> test.__index(test, 'foo') -> test.__values[foo]; if that's nil, and test.__stuff[foo], then return an empty table instead?
369 test.foo(a) -> test.__index(test, 'foo') -> test.__values[foo](a)
370 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)
371 Doesn't seem useful.
372 If test.foo is a Thing then that might be -> test.foo.__call(test.foo, a) -> could do something useful with this.
420]] 373]]
421 374
375
376
422-- Default things values. 377-- Default things values.
423-- help - help text describing this Thing. 378-- help - help text describing this Thing.
424-- default - the default value. This could be a funcion, making this a command. 379-- default - the default value. This could be a funcion, making this a command.
@@ -427,6 +382,7 @@ What about userdata? We could hijack the type() function, and dig deeper if it'
427-- required - "boolean" to say if this thing is required. TODO - Maybe fold this into types somehow, or acl? 382-- required - "boolean" to say if this thing is required. TODO - Maybe fold this into types somehow, or acl?
428-- acl - Access Control List defining security restrains. 383-- acl - Access Control List defining security restrains.
429-- boss - the Thing or person that owns this Thing, otherwise it is self owned. 384-- boss - the Thing or person that owns this Thing, otherwise it is self owned.
385Thing.names = {'?'}
430Thing.help = 'No description supplied.' 386Thing.help = 'No description supplied.'
431Thing.default = '' 387Thing.default = ''
432Thing.types = {'string'} 388Thing.types = {'string'}
@@ -451,41 +407,56 @@ end
451Thing.things = {} -- The sub things this Thing has, for modules and Stuff. 407Thing.things = {} -- The sub things this Thing has, for modules and Stuff.
452Thing.errors = {} -- A list of errors returned by isValid(). 408Thing.errors = {} -- A list of errors returned by isValid().
453 409
410Thing.__stuff = {}
411Thing.__values = {}
412
454Thing.isValid = function (self, module) -- Check if this Thing is valid, return resulting error messages in errors. 413Thing.isValid = function (self, module) -- Check if this Thing is valid, return resulting error messages in errors.
455 -- Anything that overrides this method, should call this super method first. 414 -- Anything that overrides this method, should call this super method first.
456 local pre = rawget(module, 'pre') 415 local name = self.names[1]
457 if pre then pre = pre .. '_value' else pre = 'value' end 416 local modThing = getmetatable(module)
458 local value = self[pre] 417 local thing = modThing.__stuff[name]
418 local key = thing.names[1];
419 local value = modThing.__values[key]
420
459 local t = type(value) 421 local t = type(value)
460 self.errors = {} 422 self.errors = {}
461 -- TODO - Naturally there should be formatting functions for stuffing Thing stuff into strings, and overridable output functions. 423 -- TODO - Naturally there should be formatting functions for stuffing Thing stuff into strings, and overridable output functions.
462 if 'nil' == t then 424 if 'nil' == t then
463 if self.required then table.insert(self.errors, module._NAME .. '.' .. self.names[1] .. ' is required!') end 425 if self.required then table.insert(self.errors, modThing.names[1] .. '.' .. name .. ' is required!') end
464 else 426 else
465 if self.types[1] ~= t then table.insert(self.errors, module._NAME .. '.' .. self.names[1] .. ' should be a ' .. self.types[1] .. ', but it is a ' .. type(value) .. '!') 427 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) .. '!')
466 else 428 else
467 if 'number' == t then value = '' .. value end 429 if 'number' == t then value = '' .. value end
468 if ('number' == t) or ('string' == t) then 430 if ('number' == t) or ('string' == t) then
469 if 1 ~= string.find(value, '^' .. self.pattern .. '$') then table.insert(self.errors, module._NAME .. '.' .. self.names[1] .. ' does not match pattern "' .. self.pattern .. '"!') end 431 if 1 ~= string.find(value, '^' .. self.pattern .. '$') then table.insert(self.errors, modThing.names[1] .. '.' .. name .. ' does not match pattern "' .. self.pattern .. '"!') end
470 end 432 end
471 end 433 end
472 end 434 end
435 -- TODO - Should go through self.__stuff[*]:isValid(self) as well.
473 return #(self.errors) == 0 436 return #(self.errors) == 0
474end 437end
475 438
476Thing.remove = function (self) -- Delete this Thing. 439Thing.remove = function (self) -- Delete this Thing.
477end 440end
478 441
442
479Thing.__index = function (module, key) 443Thing.__index = function (module, key)
480 -- This only works for keys that don't exist. By definition a value of nil means it doesn't exist. 444 -- This only works for keys that don't exist. By definition a value of nil means it doesn't exist.
481 local pre = rawget(module, 'pre')
482 if pre then pre = pre .. '_value' else pre = 'value' end
483 local thing = things[key]
484 -- First see if this is a Thing.
485 -- TODO - Java skang called isValid() on get(). On the other hand, doesn't seem to call it on set(), but calls it on append(). 445 -- TODO - Java skang called isValid() on get(). On the other hand, doesn't seem to call it on set(), but calls it on append().
486 -- Ah, it was doing isValid() on setStufflet(). 446 -- Ah, it was doing isValid() on setStufflet().
487 -- TODO - Call thing.func() if it exists. 447 -- TODO - Call thing.func() if it exists.
488 if thing then return thing[pre] or thing.default end 448
449 -- First see if this is a Thing.
450 local modThing = getmetatable(module)
451
452 if modThing then
453 local thing = modThing.__stuff[key]
454
455 if thing then
456 local name = thing.names[1];
457 return modThing.__values[name] or thing.__stuff[name].default
458 end
459 end
489 460
490 -- Then see if we can inherit it from Thing. 461 -- Then see if we can inherit it from Thing.
491 thing = Thing[key] 462 thing = Thing[key]
@@ -497,21 +468,16 @@ end
497 468
498Thing.__newindex = function (module, key, value) 469Thing.__newindex = function (module, key, value)
499 -- This only works for keys that don't exist. By definition a value of nil means it doesn't exist. 470 -- This only works for keys that don't exist. By definition a value of nil means it doesn't exist.
500 local pre = rawget(module, 'pre') 471 local modThing = getmetatable(module)
501 if pre then pre = pre .. '_value' else pre = 'value' end
502 local thing = things[key]
503 472
504 if thing then 473 if modThing then
505-- local name = thing.names[1]
506 -- This is a proxy table, the values never exist in the real table. 474 -- This is a proxy table, the values never exist in the real table.
507 thing[pre] = value 475 local thing = modThing.__stuff[key]
476 local name = thing.names[1]
477 modThing.__values[name] = value
508 if 'function' == type(value) then 478 if 'function' == type(value) then
509 thing.func = value 479 thing.func = value
510 local types = '' 480 local types = ''
511 for i, v in ipairs(thing.types) do
512 if 1 ~= i then types = types .. v .. ', ' end
513 end
514-- print(thing.module._NAME .. '.' .. name .. '(' .. types .. ') -> ' .. thing.help)
515 else 481 else
516 -- NOTE - invalid values are still stored, this is by design. 482 -- NOTE - invalid values are still stored, this is by design.
517 if not thing:isValid(module) then 483 if not thing:isValid(module) then
@@ -519,7 +485,6 @@ Thing.__newindex = function (module, key, value)
519 print('ERROR - ' .. v) 485 print('ERROR - ' .. v)
520 end 486 end
521 end 487 end
522-- print(thing.types[1] .. ' ' .. thing.module._NAME .. '.' .. name .. ' = ' .. (value or 'nil') .. ' -> ' .. thing.help)
523 -- TODO - Go through it's linked things and set them to. 488 -- TODO - Go through it's linked things and set them to.
524 end 489 end
525 else 490 else
@@ -555,14 +520,28 @@ thing = function (names, ...)
555 local name = names[1] 520 local name = names[1]
556 local oldNames = {} 521 local oldNames = {}
557 522
558 -- No need to bitch and return if no names, this will crash for us. 523 -- TODO - Double check this comment - No need to bitch and return if no names, this will crash for us.
559 local thing = things[name] 524 local module = params.module or params[8] or getfenv(2)
525 local modThing = getmetatable(module)
526 if nil == modThing then
527 modThing = {}
528 setmetatable(module, modThing)
529 end
530 -- Coz at module creation time, Thing is an empty table, and setmetatable(modThing, {__index = Thing}) doesn't do the same thing.
531 -- Also, module might not be an actual module, this might be Stuff.
532 if nil == modThing.__stuff then
533 for k, v in pairs(Thing) do
534 modThing[k] = modThing[k] or v
535 end
536 end
537 local thing = modThing.__stuff[name]
560 if not thing then -- This is a new Thing. 538 if not thing then -- This is a new Thing.
561 new = true 539 new = true
562 thing = {} 540 thing = {}
563 -- Grab the environment of the calling function, so this new thing automatically becomes a global in it. 541 -- Grab the environment of the calling function, so this new thing automatically becomes a global in it.
564 thing.module = getfenv(2) 542 thing.module = module
565 thing.names = names 543 thing.names = names
544 setmetatable(thing, {__index = Thing})
566 end 545 end
567 546
568 -- Pull out positional arguments. 547 -- Pull out positional arguments.
@@ -573,7 +552,6 @@ thing = function (names, ...)
573 thing.required = params[5] or thing.required 552 thing.required = params[5] or thing.required
574 thing.acl = params[6] or thing.acl 553 thing.acl = params[6] or thing.acl
575 thing.boss = params[7] or thing.boss 554 thing.boss = params[7] or thing.boss
576 thing.module = params[8] or thing.module -- Mostly for things like C functions, where get/setfenv() wont do what we need.
577 555
578 -- Pull out named arguments. 556 -- Pull out named arguments.
579 for k, v in pairs(params) do 557 for k, v in pairs(params) do
@@ -596,54 +574,69 @@ thing = function (names, ...)
596 if types then types = typ .. ',' .. types else types = typ end 574 if types then types = typ .. ',' .. types else types = typ end
597 thing.types = csv2table(types) 575 thing.types = csv2table(types)
598 576
599 if new then setmetatable(thing, Thing) end
600
601 -- Remove old names, then stash the Thing under all of it's new names. 577 -- Remove old names, then stash the Thing under all of it's new names.
602 for i, v in ipairs(oldNames) do 578 for i, v in ipairs(oldNames) do
603 thing.module.things[v] = nil 579 modThing.__stuff[v] = nil
604 things[v] = nil
605 end 580 end
606 for i, v in ipairs(thing.names) do 581 for i, v in ipairs(thing.names) do
607 thing.module.things[v] = thing 582 modThing.__stuff[v] = thing
608 things[v] = thing
609 end 583 end
610 584
611 -- This triggers the Thing.__newindex metamethod above. If nothing else, it triggers thing.isValid() 585 -- This triggers the Thing.__newindex metamethod above. If nothing else, it triggers thing.isValid()
612 if new then thing.module[name] = thing.default end 586 if new then module[name] = thing.default end
613end 587end
614 588
615 589
616-- skang.new() Creats a new copy of a module. 590copy = function (module, name)
617--[[ 591 local result = {}
618 A module isn't exactly a thing, it has Thing as it's metatable though. 592 local thing = {}
593 local modThing = getmetatable(module)
619 594
620 local test = require 'test' 595 for k, v in pairs(Thing) do
621 skang.moduleBegin('test', ...) 596 thing[k] = v
622 setmetatable(test, Thing) 597 end
623 skang.thing('foo', ...)
624 setmetatable(test.module.things.foo, Thing)
625 test.module.things.foo = skang.things.foo
626 local tester = skang.new(test, 'pre')
627 598
628 skang.things.foo.value 599 thing.__values = {}
629 skang.things.foo.pre_value 600 for k, v in pairs(modThing.__values) do
601 thing.__values[k] = v
602 end
630 603
604 thing.__stuff = modThing.__stuff
605 thing.names = {name}
606 setmetatable(thing, {__index = Thing})
607 setmetatable(result, thing)
631 608
632 ]] 609 return result
633new = function (module, pre) 610end
634 local result = {}
635 611
636 setmetatable(result, Thing)
637 result.pre = pre
638 -- Loop through the Things in thing
639 -- TODO - Will have to be a deeper copy if it's a Stuff?
640 for k, v in pairs(module.things) do
641 v[pre .. '_value'] = v.value
642-- things[pre .. '_' .. k].module = result
643 end
644 612
645 return result 613get = function (stuff, key, name)
646 end 614 local result
615 local thing = getmetatable(stuff)
616 if thing then
617 local this = thing.__stuff[key]
618 if this then result = this[name] end
619 end
620 return result
621end
622
623
624reset = function (stuff, key, name)
625 local thing = getmetatable(stuff)
626 if thing then
627 local this = thing.__stuff[key]
628 if this then this[name] = nil end
629 end
630end
631
632
633set = function (stuff, key, name, value)
634 local thing = getmetatable(stuff)
635 if thing then
636 local this = thing.__stuff[key]
637 if this then this[name] = value end
638 end
639end
647 640
648 641
649-- TODO - Some function stubs, for now. Fill them up later. 642-- TODO - Some function stubs, for now. Fill them up later.
diff --git a/ClientHamr/GuiLua/test.lua b/ClientHamr/GuiLua/test.lua
index 2f93c94..c983943 100644
--- a/ClientHamr/GuiLua/test.lua
+++ b/ClientHamr/GuiLua/test.lua
@@ -48,22 +48,21 @@ end
48local skang = require 'skang' 48local skang = require 'skang'
49local test = require 'test' 49local test = require 'test'
50local test_c = require 'test_c' 50local test_c = require 'test_c'
51local copy_test = skang.new(test, 'copy') 51local copy = skang.copy(test, 'copy')
52 52
53print('End ' .. test.bar .. ' ' .. test.VERSION .. ' ' .. skang.things.ffunc.help .. ' ->> ' .. skang.things.f.action) 53print('End ' .. test.bar .. ' ' .. test.VERSION .. ' ' .. skang.get(test, 'ffunc', 'help') .. ' ->> ' .. skang.get(test, 'f', 'action'))
54print('foo = ' .. test.foo .. ' ->> ' .. skang.things.foo.help) 54print('foo = ' .. test.foo .. ' ->> ' .. skang.get(test, 'foo', 'help'))
55print('cfunc ->> ' .. skang.things.cfunc.help) 55print('cfunc ->> ' .. skang.get(test_c, 'cfunc', 'help'))
56test.ffunc('one', 2) 56test.ffunc('one', 2)
57test_c.cfunc(0, 'zero') 57test_c.cfunc(0, 'zero')
58--skang.things.ffunc('seven', 'aight')
59print('') 58print('')
60 59
61test.f = 42 60test.f = 42
62print('f is now ' .. test.fooble .. ' ' .. test.f .. ' ' .. skang.things.f.help .. ' ' .. skang.things.fooble.help) 61print('f is now ' .. test.fooble .. ' ' .. test.f)
63print('copy_f is now ' .. copy_test.fooble .. ' ' .. copy_test.f) 62print('copy_f is now ' .. copy.fooble .. ' ' .. copy.f)
64copy_test.f = 24 63copy.f = 24
65print('f is now ' .. test.fooble .. ' ' .. test.f .. ' ' .. skang.things.f.help .. ' ' .. skang.things.fooble.help) 64print('f is now ' .. test.fooble .. ' ' .. test.f)
66print('copy_f is now ' .. copy_test.fooble .. ' ' .. copy_test.f) 65print('copy_f is now ' .. copy.fooble .. ' ' .. copy.f)
67test.f = nil 66test.f = nil
68print('f is now ' .. test.fooble .. ' ' .. test.f) 67print('f is now ' .. test.fooble .. ' ' .. test.f)
69test.fooble = 42 68test.fooble = 42
@@ -92,10 +91,9 @@ print(skang.isBoolean(function (a) return false end))
92print('') 91print('')
93 92
94-- Make it required, even though it was anyway. 93-- Make it required, even though it was anyway.
95skang.thing{'f', required = true} 94skang.set(test, 'f', 'required', true)
96-- First, disable the default value, so we see "is required" errors. 95-- Disable the default value, so we see "is required" errors.
97-- Coz using the above syntax means that default is never passed to skang.thing, since it's nil. 96skang.reset(test, 'f', 'default')
98skang.things.f.default = nil
99test.fooble = 42 97test.fooble = 42
100test.fooble = 'Should fail.' 98test.fooble = 'Should fail.'
101test.fooble = 42 99test.fooble = 42
@@ -105,3 +103,13 @@ test.fooble = 42
105test.fooble = true 103test.fooble = true
106test.f = 42 104test.f = 42
107test.f = nil 105test.f = nil
106print('')
107
108skang.set(test, 'f', 'required', false)
109test.f = 42
110test.f = nil
111skang.set(test, 'f', 'default', 999)
112test.f = 42
113test.f = nil
114print(test.fooble .. ' ' .. test.f)
115print(skang.get(test, 'f', 'default'))