diff options
author | David Walter Seikel | 2014-03-20 14:41:00 +1000 |
---|---|---|
committer | David Walter Seikel | 2014-03-20 14:41:00 +1000 |
commit | 601ffda9dc282b25e835b92e9c9afb0ba2521c15 (patch) | |
tree | 5e62031cadaa78e10c1d9879bfb80d71fa811362 /ClientHamr | |
parent | TODO++ (diff) | |
download | SledjHamr-601ffda9dc282b25e835b92e9c9afb0ba2521c15.zip SledjHamr-601ffda9dc282b25e835b92e9c9afb0ba2521c15.tar.gz SledjHamr-601ffda9dc282b25e835b92e9c9afb0ba2521c15.tar.bz2 SledjHamr-601ffda9dc282b25e835b92e9c9afb0ba2521c15.tar.xz |
Rewrite moduleBegin.
Diffstat (limited to 'ClientHamr')
-rw-r--r-- | ClientHamr/GuiLua/skang.lua | 98 |
1 files changed, 44 insertions, 54 deletions
diff --git a/ClientHamr/GuiLua/skang.lua b/ClientHamr/GuiLua/skang.lua index 23615ae..c3b0e33 100644 --- a/ClientHamr/GuiLua/skang.lua +++ b/ClientHamr/GuiLua/skang.lua | |||
@@ -54,14 +54,32 @@ The old skang argument types are - | |||
54 | 54 | ||
55 | -- Wrapping the entire module in do .. end helps if people just join a bunch of modules together, which apparently is popular. | 55 | -- Wrapping the entire module in do .. end helps if people just join a bunch of modules together, which apparently is popular. |
56 | -- By virtue of the fact we are stuffing our result into package.loaded[], just plain running this works as "loading the module". | 56 | -- By virtue of the fact we are stuffing our result into package.loaded[], just plain running this works as "loading the module". |
57 | -- TODO - Except for the "passing the name in as ..." part. B-( | ||
58 | do -- Only I'm not gonna indent this. | 57 | do -- Only I'm not gonna indent this. |
59 | 58 | ||
60 | 59 | -- This needs to start as local, then get wrapped a couple of times, eventually being made public as moduleBegin(). | |
61 | local skangModuleBegin = function (name, author, copyright, version, timestamp, skin) | 60 | local skangModuleBegin = function (name, author, copyright, version, timestamp, skin) |
62 | local _M = {} -- This is what we return to require(). | 61 | local _M = {} -- This is what we return to require(). |
63 | _M._NAME = name -- Catch the module name passed in from require(), so that the file name can change. | 62 | |
64 | _M._M = _M -- So that references to _M below the setfenv() actually go to the real _M. | 63 | package.loaded[name] = _M -- Stuff the result into where require() can find it, instead of returning it at the end. |
64 | -- Returning it at the end does the same thing. | ||
65 | -- This is so that we can have all the module stuff at the top, in this function. | ||
66 | -- Should do this before any further require(), so that circular references don't blow out. | ||
67 | |||
68 | -- Save the callers environment. | ||
69 | local savedEnvironment = getfenv(3) | ||
70 | |||
71 | -- Clone the environment into _M, so the module can access everything as usual after the setfenv() below. | ||
72 | --[[ TODO - Check if this also clones _G or _ENV. And see if it leaks stuff in either direction. | ||
73 | local _G = _G -- Only sets a local _G for this function. | ||
74 | _M._G = _G -- This clone loop might do this, but we don't want to be able to access the old _G from outside via this leak. | ||
75 | In Lua 5.1 at least, _G was special. In 5.2, _ENV sorta replaces setfenv(), but no idea if this clone loop stomps on that. | ||
76 | ]] | ||
77 | for k, v in pairs(savedEnvironment) do | ||
78 | _M[k] = v | ||
79 | end | ||
80 | |||
81 | _M._M = _M -- So that references to _M below the setfenv() actually go to the real _M. | ||
82 | _M._NAME = name | ||
65 | _M._PACKAGE = string.gsub(_M._NAME, "[^.]*$", "") -- Strip the name down to the package name. | 83 | _M._PACKAGE = string.gsub(_M._NAME, "[^.]*$", "") -- Strip the name down to the package name. |
66 | 84 | ||
67 | -- TODO - Should parse in an entire copyright message, and strip that down into bits, to put back together. | 85 | -- TODO - Should parse in an entire copyright message, and strip that down into bits, to put back together. |
@@ -72,46 +90,19 @@ local skangModuleBegin = function (name, author, copyright, version, timestamp, | |||
72 | -- TODO - If there's no skin passed in, try to find the file skin .. '.skang' and load that instead. | 90 | -- TODO - If there's no skin passed in, try to find the file skin .. '.skang' and load that instead. |
73 | _M.DEFAULT_SKANG = skin | 91 | _M.DEFAULT_SKANG = skin |
74 | 92 | ||
75 | package.loaded[_M._NAME] = _M -- Stuff the result into where require() can find it, instead of returning it at the end. | 93 | |
76 | -- Returning it at the end does the same thing. | 94 | --_G[_M._NAME] = _M -- Stuff it into a global of the same name. |
77 | -- This is so that we can have all the module stuff at the top. | 95 | -- Not such a good idea to stomp on global name space. |
78 | -- Should do this before any further require(), so that circular references don't blow out. | 96 | -- It's also redundant coz we get stored in package.loaded[_M._NAME] anyway. |
79 | 97 | -- This is why module() is broken. | |
80 | --_G[_M._NAME] = _M -- Stuff it into a global of the same name. | 98 | |
81 | -- Not such a good idea to stomp on global name space. | 99 | _M.savedEnvironment = savedEnvironment |
82 | -- It's also redundant coz we get stored in package.loaded[_M._NAME] anyway. | 100 | -- setfenv() sets the environment for the FUNCTION, stack level deep. |
83 | -- This is why module() is broken. | ||
84 | |||
85 | --local _G = _G -- Stop stuff from here leaking into the callers _G. | ||
86 | -- Also works around the setfenv() below discarding all the old globals. | ||
87 | -- Though now we have to use _G.foo to access globals. | ||
88 | |||
89 | -- An alternative to the local _G is to declare as local ALL our imports here. May be worthwhile to do both this and local _G? | ||
90 | -- basic, is it called "basic", might be called "base"? Might have to include individual names. | ||
91 | _M.print = print | ||
92 | _M.getfenv = getfenv | ||
93 | _M.setfenv = setfenv | ||
94 | _M.require = require | ||
95 | _M.coroutine = coroutine -- Apparently this is part of basic, but it comes in it's own table anyway. | ||
96 | _M.package = package | ||
97 | _M.string = string | ||
98 | _M.table = table | ||
99 | _M.math = math | ||
100 | _M.io = io | ||
101 | _M.os = os | ||
102 | _M.debug = debug | ||
103 | |||
104 | _M.savedEnvironment = getfenv(3) | ||
105 | -- setfenv() sets the environment for the FUNCTION, but we are not in a function. | ||
106 | -- Though if we are being require()ed, then require() calls a loader, which calls us, hence we are the function. | ||
107 | -- The number is the stack level - | 101 | -- The number is the stack level - |
108 | -- 0 running thread, 1 current function, 2 function that called this function, etc | 102 | -- 0 running thread, 1 current function, 2 function that called this function, etc |
109 | setfenv(3, _M) -- Use the result for our internal global environment, so we don't need to qualify our internal names. | 103 | setfenv(3, _M) -- Use the result for the modules internal global environment, so they don't need to qualify internal names. |
110 | -- So the below "_M.bar" becomes "bar". Which might not be what we want, since we are using | 104 | -- Dunno if this causes problems with the do ... end style of joining modules. It does. So we need to restore in moduleEnd(). |
111 | -- _M.bar for the Thing, not the local bar the Thing wraps. So we leave _M.bar as is, coz we have _M._M above. B-) | 105 | -- 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. |
112 | -- Since _M is empty at this point, we loose the other globals, but that's we why declare local copies of stuff above. | ||
113 | -- Dunno if this causes problems with the do ... end style of joining modules. It does. | ||
114 | -- 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. | ||
115 | 106 | ||
116 | return _M | 107 | return _M |
117 | end | 108 | end |
@@ -122,7 +113,8 @@ local smb = function (name, author, copyright, version, timestamp, skin) | |||
122 | return result | 113 | return result |
123 | end | 114 | end |
124 | 115 | ||
125 | local _M = smb(..., 'David Seikel', '2014', '0.0', '2014-03-19 19:01:00', nil) | 116 | -- Call this now, via the above wrapper, so that from now on, this is like any other module. |
117 | local _M = smb('skang', 'David Seikel', '2014', '0.0', '2014-03-19 19:01:00') | ||
126 | 118 | ||
127 | ThingSpace = {} | 119 | ThingSpace = {} |
128 | ThingSpace.cache = {} | 120 | ThingSpace.cache = {} |
@@ -130,13 +122,20 @@ ThingSpace.commands = {} | |||
130 | ThingSpace.modules = {} | 122 | ThingSpace.modules = {} |
131 | ThingSpace.parameters = {} | 123 | ThingSpace.parameters = {} |
132 | ThingSpace.widgets = {} | 124 | ThingSpace.widgets = {} |
125 | -- Actually stuff ourself into ThingSpace. | ||
126 | ThingSpace.modules[_NAME] = {module = _M, name = _NAME, } | ||
133 | 127 | ||
128 | -- This is the final version that we export. Finally we can include the ThingSpace stuff. | ||
134 | moduleBegin = function (name, author, copyright, version, timestamp, skin) | 129 | moduleBegin = function (name, author, copyright, version, timestamp, skin) |
135 | local result = skangModuleBegin(name, author, copyright, version, timestamp, skin) | 130 | local result = skangModuleBegin(name, author, copyright, version, timestamp, skin) |
136 | ThingSpace.modules[name] = {module = _M, name = name, } | 131 | ThingSpace.modules[name] = {module = result, name = name, } |
137 | return result | 132 | return result |
138 | end | 133 | end |
139 | 134 | ||
135 | -- Restore the environment. | ||
136 | moduleEnd = function (module) | ||
137 | setfenv(2, module.savedEnvironment) | ||
138 | end | ||
140 | 139 | ||
141 | --[[ | 140 | --[[ |
142 | Thing = {} | 141 | Thing = {} |
@@ -148,9 +147,6 @@ So in newParam and newCommand - | |||
148 | 147 | ||
149 | 148 | ||
150 | -- skang.newParam stashes the default value into _M['bar'], and the details into ThingSpace.parameters['bar']. | 149 | -- skang.newParam stashes the default value into _M['bar'], and the details into ThingSpace.parameters['bar']. |
151 | -- Actually, if it's not required, and there's no default, then skip setting _M['bar']. | ||
152 | -- Could even use _index to skip setting it if it's not required and there is a default. | ||
153 | -- Also should add a metatable, and __newindex() that passes all setting of this variable to skang so it can update other stuff like linked widgets. | ||
154 | -- TODO - If it's not required, and there's no default, then skip setting _M['bar']. | 150 | -- TODO - If it's not required, and there's no default, then skip setting _M['bar']. |
155 | -- TODO - Could even use __index to skip setting it if it's not required and there is a default. | 151 | -- TODO - Could even use __index to skip setting it if it's not required and there is a default. |
156 | -- TODO - Should add a metatable, and __newindex() that passes all setting of this variable to skang so it can update other stuff like linked widgets. | 152 | -- TODO - Should add a metatable, and __newindex() that passes all setting of this variable to skang so it can update other stuff like linked widgets. |
@@ -201,11 +197,6 @@ newCommand(_M, 'set', 'name,data', 'Set the current value of an existing Thing. | |||
201 | newCommand(_M, 'quit', '', 'Quit, exit, remove thyself.', quit) | 197 | newCommand(_M, 'quit', '', 'Quit, exit, remove thyself.', quit) |
202 | 198 | ||
203 | 199 | ||
204 | -- Restore the environment. | ||
205 | moduleEnd = function (module) | ||
206 | setfenv(2, module.savedEnvironment) | ||
207 | end | ||
208 | |||
209 | moduleEnd(_M) | 200 | moduleEnd(_M) |
210 | 201 | ||
211 | end | 202 | end |
@@ -315,4 +306,3 @@ end | |||
315 | -- Gotta check out this _ENV thing, 5.2 only. Seems to replace the need for setfenv(). Seems like setfenv should do what we want, and is more backward compatible. | 306 | -- Gotta check out this _ENV thing, 5.2 only. Seems to replace the need for setfenv(). Seems like setfenv should do what we want, and is more backward compatible. |
316 | -- "_ENV is not supported directly in 5.1, so its use can prevent a module from remaining compatible with 5.1. | 307 | -- "_ENV is not supported directly in 5.1, so its use can prevent a module from remaining compatible with 5.1. |
317 | -- Maybe you can simulate _ENV with setfenv and trapping gets/sets to it via __index/__newindex metamethods, or just avoid _ENV." | 308 | -- Maybe you can simulate _ENV with setfenv and trapping gets/sets to it via __index/__newindex metamethods, or just avoid _ENV." |
318 | --[[ This is a Lua version of what module() does. Apparently the _LOADED stuff is needed somehow, even though it's a local? Think that was bogus. | ||