diff options
author | David Walter Seikel | 2014-03-28 03:20:57 +1000 |
---|---|---|
committer | David Walter Seikel | 2014-03-28 03:20:57 +1000 |
commit | 0d31077404dd87f4874c2db2acc9732f2412d91f (patch) | |
tree | ed95b2f10f826f6c3d212ffee3ad9a364fb5b211 /ClientHamr | |
parent | A new csv2table() function. (diff) | |
download | SledjHamr-0d31077404dd87f4874c2db2acc9732f2412d91f.zip SledjHamr-0d31077404dd87f4874c2db2acc9732f2412d91f.tar.gz SledjHamr-0d31077404dd87f4874c2db2acc9732f2412d91f.tar.bz2 SledjHamr-0d31077404dd87f4874c2db2acc9732f2412d91f.tar.xz |
Rewrite skang.thing() to allow positional and named arguments, allow changing Things, plus some more tweaks.
Diffstat (limited to 'ClientHamr')
-rw-r--r-- | ClientHamr/GuiLua/skang.lua | 98 | ||||
-rw-r--r-- | ClientHamr/GuiLua/test.lua | 3 |
2 files changed, 74 insertions, 27 deletions
diff --git a/ClientHamr/GuiLua/skang.lua b/ClientHamr/GuiLua/skang.lua index 0aeda72..b88d293 100644 --- a/ClientHamr/GuiLua/skang.lua +++ b/ClientHamr/GuiLua/skang.lua | |||
@@ -272,6 +272,13 @@ __newindex could catch a table being assigned - test.foo = {widget = '...', acl= | |||
272 | ]] | 272 | ]] |
273 | 273 | ||
274 | -- Default things values. | 274 | -- Default things values. |
275 | -- help - help text describing this Thing. | ||
276 | -- default - the default value. This could be a funcion, making this a command. | ||
277 | -- types - a comma separated list of types. The first is the type of the Thing itself, the rest are for multi value Things. Or argument types for commands. | ||
278 | -- widget - default widget command arguments for creating this Thing as a widget. | ||
279 | -- required - "boolean" to say if this thing is required. TODO - Maybe fold this into types somehow, or acl? | ||
280 | -- acl - Access Control List defining security restrains. | ||
281 | -- boss - the Thing or person that owns this Thing, otherwise it is self owned. | ||
275 | Thing.help = 'No description supplied.' | 282 | Thing.help = 'No description supplied.' |
276 | Thing.default = '' | 283 | Thing.default = '' |
277 | Thing.types = {'string'} | 284 | Thing.types = {'string'} |
@@ -378,43 +385,80 @@ end | |||
378 | -- types - a comma separated list of types. The first is the type of the Thing itself, the rest are for multi value Things. Or argument types for commands. | 385 | -- types - a comma separated list of types. The first is the type of the Thing itself, the rest are for multi value Things. Or argument types for commands. |
379 | -- widget - default widget command arguments for creating this Thing as a widget. | 386 | -- widget - default widget command arguments for creating this Thing as a widget. |
380 | -- required - "boolean" to say if this thing is required. TODO - Maybe fold this into types somehow, or acl? | 387 | -- required - "boolean" to say if this thing is required. TODO - Maybe fold this into types somehow, or acl? |
381 | -- acl - Access Control List defining security restrains. | 388 | -- skang.thing() Creates a new Thing, or changes an existing one. |
382 | -- boss - the Thing or person that owns this Thing, otherwise it is self owned. | 389 | -- It can be called with positional arguments - (names, help, default, types, widget, required, acl, boss) |
383 | thing = function (names, help, default, types, widget, required, acl, boss) | 390 | -- Or it can be called with a table - {names, help, pattern='...', acl='rwx'} |
384 | -- Grab the environment of the calling function, so this new thing automatically becomes a global in it. | 391 | -- names - a comma seperated list of names, aliases, and shortcuts. The first one is the official name. |
385 | module = getfenv(2) | 392 | -- If this is not a new thing, then only the first one is used to look it up. |
393 | -- So to change names, use skang.thing{'oldName', names='newName,otherNewName'} | ||
394 | thing = function (names, ...) | ||
395 | local params = {...} | ||
396 | local new = false | ||
397 | |||
398 | -- Check if it was called as a table, and pull the names out of the table. | ||
399 | if 'table' == type(names) then | ||
400 | params = names | ||
401 | names = params[1] | ||
402 | table.remove(params, 1) | ||
403 | end | ||
386 | 404 | ||
387 | -- Break out the names. | 405 | -- Break out the names. |
388 | local n = {} | 406 | names = csv2table(names) |
389 | local i = 1 | 407 | local name = names[1] |
390 | for v in string.gmatch(names, '([^,]+)') do | 408 | local oldNames = {} |
391 | n[i] = v | 409 | |
392 | i = i + 1 | 410 | -- No need to bitch and return if no names, this will crash for us. |
411 | local thing = things[name] | ||
412 | if not thing then -- This is a new Thing. | ||
413 | new = true | ||
414 | thing = {} | ||
415 | -- Grab the environment of the calling function, so this new thing automatically becomes a global in it. | ||
416 | thing.module = getfenv(2) | ||
417 | thing.names = names | ||
393 | end | 418 | end |
394 | -- TODO - Should bitch and return if no names, has to be at least one name. | ||
395 | local name = n[1] | ||
396 | 419 | ||
397 | -- Find type, default to string, then break out the other types. | 420 | -- Pull out positional arguments. |
398 | local t = {type(default)} | 421 | thing.help = params[1] or thing.help |
399 | if 'nil' == t[1] then t[1] = 'string' end | 422 | thing.default = params[2] or thing.default |
400 | if types then | 423 | local types = params[3] or table.concat(thing.types or {}, ',') |
401 | i = 2 | 424 | thing.widget = params[4] or thing.widget |
402 | for v in string.gmatch(types, '([^,]+)') do | 425 | thing.required = params[5] or thing.required |
403 | t[i] = v | 426 | thing.acl = params[6] or thing.acl |
404 | i = i + 1 | 427 | thing.boss = params[7] or thing.boss |
428 | |||
429 | -- PUll out named arguments. | ||
430 | for k, v in pairs(params) do | ||
431 | if 'string' == type(k) then | ||
432 | if 'types' == k then types = v | ||
433 | elseif 'names' == k then | ||
434 | oldNames = thing.names | ||
435 | thing.names = cvs2table(v) | ||
436 | else thing[k] = v | ||
437 | end | ||
405 | end | 438 | end |
406 | end | 439 | end |
407 | 440 | ||
408 | -- Set it all up. | 441 | thing.required = isBoolean(thing.required) |
409 | -- TODO - might want to merge into pre existing Thing instead of over writing like this. OOOR clone so there's a second copy. | 442 | |
410 | local thing = {module = module, names = n, help = help, default = default, types = t, widget = widget, required = isBoolean(required), acl = acl, boss = boss, } | 443 | -- Find type, default to string, then break out the other types. |
411 | setmetatable(thing, Thing) | 444 | local typ = type(thing.default) |
412 | -- Stash the Thing under all of it's names. | 445 | if 'nil' == typ then typ = 'string' end |
446 | thing.types = {} | ||
447 | if types then types = typ .. ',' .. types else types = typ end | ||
448 | thing.types = csv2table(types) | ||
449 | |||
450 | if new then setmetatable(thing, Thing) end | ||
451 | |||
452 | -- Remove old names, then stash the Thing under all of it's new names. | ||
453 | for i, v in ipairs(oldNames) do | ||
454 | things[v] = nil | ||
455 | end | ||
413 | for i, v in ipairs(thing.names) do | 456 | for i, v in ipairs(thing.names) do |
414 | things[v] = thing | 457 | things[v] = thing |
415 | end | 458 | end |
416 | -- This triggers the Thing.__newindex metamethod above. | 459 | |
417 | module[name] = default | 460 | -- This triggers the Thing.__newindex metamethod above. If nothing else, it triggers thing.isValid() |
461 | if new then thing.module[name] = thing.default end | ||
418 | end | 462 | end |
419 | 463 | ||
420 | --[[ TODO - It might be worth it to combine parameters and commands, since in Lua, functions are first class types like numbers and strings. | 464 | --[[ TODO - It might be worth it to combine parameters and commands, since in Lua, functions are first class types like numbers and strings. |
diff --git a/ClientHamr/GuiLua/test.lua b/ClientHamr/GuiLua/test.lua index b1ab691..2115098 100644 --- a/ClientHamr/GuiLua/test.lua +++ b/ClientHamr/GuiLua/test.lua | |||
@@ -87,7 +87,10 @@ print(skang.isBoolean('Nope')) | |||
87 | print(skang.isBoolean(function (a) return false end)) | 87 | print(skang.isBoolean(function (a) return false end)) |
88 | print('') | 88 | print('') |
89 | 89 | ||
90 | -- Make it required, even though it was anyway. | ||
91 | skang.thing{'f', required = true} | ||
90 | -- First, disable the default value, so we see "is required" errors. | 92 | -- First, disable the default value, so we see "is required" errors. |
93 | -- Coz using the above syntax means that default is never passed to skang.thing, since it's nil. | ||
91 | skang.things.f.default = nil | 94 | skang.things.f.default = nil |
92 | test.fooble = 42 | 95 | test.fooble = 42 |
93 | test.fooble = 'Should fail.' | 96 | test.fooble = 'Should fail.' |