diff options
author | David Walter Seikel | 2012-02-05 15:38:46 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-02-05 15:38:46 +1000 |
commit | 4c45884e658800a2528381cb1368514499d592d8 (patch) | |
tree | 588b8f4ea1e45cd02c84eb2ee3178dc1bb7f7458 /LuaSL/src | |
parent | Commentry. (diff) | |
download | SledjHamr-4c45884e658800a2528381cb1368514499d592d8.zip SledjHamr-4c45884e658800a2528381cb1368514499d592d8.tar.gz SledjHamr-4c45884e658800a2528381cb1368514499d592d8.tar.bz2 SledjHamr-4c45884e658800a2528381cb1368514499d592d8.tar.xz |
Implement more of the state handling stuff, with copious comments.
Diffstat (limited to 'LuaSL/src')
-rw-r--r-- | LuaSL/src/LSL.lua | 74 | ||||
-rw-r--r-- | LuaSL/src/LuaSL_compile.c | 4 |
2 files changed, 58 insertions, 20 deletions
diff --git a/LuaSL/src/LSL.lua b/LuaSL/src/LSL.lua index 1b59cf3..0b02077 100644 --- a/LuaSL/src/LSL.lua +++ b/LuaSL/src/LSL.lua | |||
@@ -1,7 +1,7 @@ | |||
1 | -- A module of LSL stuffs. | 1 | -- A module of LSL stuffs. |
2 | -- TODO - currently there is a constants.lsl file. Move it into here. | 2 | -- TODO - currently there is a constants.lsl file. Move it into here. |
3 | -- It contains LSL constants and ll*() functions stubs. | 3 | -- It contains LSL constants and ll*() functions stubs. |
4 | -- The compiler compiles that into a LSL_Scripts structure at startup, | 4 | -- The compiler compiles that into a LSL_Scripts structure at startup, |
5 | -- then uses that for function and variable lookups, as well as looking up in the current script. | 5 | -- then uses that for function and variable lookups, as well as looking up in the current script. |
6 | -- I can run this at compiler startup time, then iterate through the LSL table from C to generate that LSL_Script structure. | 6 | -- I can run this at compiler startup time, then iterate through the LSL table from C to generate that LSL_Script structure. |
7 | 7 | ||
@@ -22,11 +22,13 @@ written by different people or because they are different versions of | |||
22 | the same module loaded simultaneously. To address this, one may instead | 22 | the same module loaded simultaneously. To address this, one may instead |
23 | use a lightuserdata (pointer to variable of static linkage to ensure | 23 | use a lightuserdata (pointer to variable of static linkage to ensure |
24 | global uniqueness) for this key or store the metatable as an | 24 | global uniqueness) for this key or store the metatable as an |
25 | upvalue--either way is a bit more efficient and less error prone. | 25 | upvalue--either way is a bit more efficient and less error prone. |
26 | ]] | 26 | ]] |
27 | 27 | ||
28 | local LSL = {}; | 28 | local LSL = {}; |
29 | 29 | ||
30 | -- LSL constants. | ||
31 | |||
30 | LSL.PI = 3.14159265358979323846264338327950; | 32 | LSL.PI = 3.14159265358979323846264338327950; |
31 | LSL.PI_BY_TWO = LSL.PI / 2; -- 1.57079632679489661923132169163975 | 33 | LSL.PI_BY_TWO = LSL.PI / 2; -- 1.57079632679489661923132169163975 |
32 | LSL.TWO_PI = LSL.PI * 2; -- 6.28318530717958647692528676655900 | 34 | LSL.TWO_PI = LSL.PI * 2; -- 6.28318530717958647692528676655900 |
@@ -196,7 +198,7 @@ LSL.x = 0.0; | |||
196 | LSL.y = 0.0; | 198 | LSL.y = 0.0; |
197 | LSL.z = 0.0; | 199 | LSL.z = 0.0; |
198 | 200 | ||
199 | -- Functions. | 201 | -- ll*() functions. |
200 | 202 | ||
201 | function --[[float]] LSL.llPow(--[[float]] number,--[[float]] places) return 0.0 end; | 203 | function --[[float]] LSL.llPow(--[[float]] number,--[[float]] places) return 0.0 end; |
202 | function --[[float]] LSL.llFrand(--[[float]] max) return 0.0 end; | 204 | function --[[float]] LSL.llFrand(--[[float]] max) return 0.0 end; |
@@ -295,53 +297,89 @@ function LSL.llWhisper(--[[integer]] channel, --[[string]] text) print("Channe | |||
295 | 297 | ||
296 | function LSL.llMessageLinked(--[[integer]] link,--[[integer]] num, --[[string]] text, --[[key]] aKey) end; | 298 | function LSL.llMessageLinked(--[[integer]] link,--[[integer]] num, --[[string]] text, --[[key]] aKey) end; |
297 | 299 | ||
300 | -- Crements stuff. | ||
301 | |||
298 | function LSL.preDecrement(name) _G[name] = _G[name] - 1; return _G[name]; end; | 302 | function LSL.preDecrement(name) _G[name] = _G[name] - 1; return _G[name]; end; |
299 | function LSL.preIncrement(name) _G[name] = _G[name] + 1; return _G[name]; end; | 303 | function LSL.preIncrement(name) _G[name] = _G[name] + 1; return _G[name]; end; |
300 | function LSL.postDecrement(name) local temp = _G[name]; _G[name] = _G[name] - 1; return temp; end; | 304 | function LSL.postDecrement(name) local temp = _G[name]; _G[name] = _G[name] - 1; return temp; end; |
301 | function LSL.postIncrement(name) local temp = _G[name]; _G[name] = _G[name] + 1; return temp; end; | 305 | function LSL.postIncrement(name) local temp = _G[name]; _G[name] = _G[name] + 1; return temp; end; |
302 | 306 | ||
307 | -- State stuff | ||
308 | |||
303 | local currentState = {} | 309 | local currentState = {} |
310 | |||
304 | function LSL.stateChange(x) | 311 | function LSL.stateChange(x) |
312 | if currentState ~= x then -- Changing to the same state is a NOP. | ||
313 | -- TODO - Should clear out pending events, except timer() | ||
314 | -- Also forget about any event setup that needs setting up via some ll*() function, except timer(). | ||
305 | if nil ~= currentState.state_exit then | 315 | if nil ~= currentState.state_exit then |
306 | currentState.state_exit(); | 316 | currentState.state_exit(); |
307 | end | 317 | end |
308 | currentState = x; | 318 | currentState = x; |
309 | if nil ~= currentState.state_entry then | 319 | --[[ Never return to the current states event handler. In theory. lol |
310 | currentState.state_entry(); | 320 | Notably, it's not actually legal to do a state change from a function, only from handlers. |
321 | There is a hack though, but it's unsupported, so I don't have to worry about it so much. | ||
322 | |||
323 | Write out "state new;" as "return _LSL.stateChange(newState);", with stateChange() returning new.state_entry()) which will force two tail calls. | ||
324 | |||
325 | The caller of stateChange() might be a function rather than an event handler. | ||
326 | Which will return to the event handler (possibly via other nested function calls) as if the state never changed. | ||
327 | http://lslwiki.net/lslwiki/wakka.php?wakka=FunctionStateChangeHack seems to imply that this is exactly what LSL does. | ||
328 | Soooo, this might actually work perfectly. | ||
329 | Except for one minor quirk, as that page shows - only the top level function's state sticks, unless the handler does one to, then the handlers one overrides things. | ||
330 | Which I can probably ignore anyway, as this entire calling states within functions thing is an unsupported hack. | ||
331 | ]] | ||
332 | if nil ~= currentState.state_entry then | ||
333 | return currentState.state_entry(); | ||
311 | end | 334 | end |
335 | end | ||
312 | end; | 336 | end; |
313 | 337 | ||
338 | function LSL.mainLoop(x) | ||
339 | LSL.stateChange(x); | ||
340 | --[[ TODO - | ||
341 | Sits around waiting for events. This should be "wait for a message" in luaproc. | ||
342 | Incoming events can be the same format as the OpenSim SID.event.* protocol on the wiki. | ||
343 | When we get an event, run it, then go back to waiting. | ||
344 | |||
345 | Need a FIFO stack of incoming events. | ||
346 | Which will be in the C main thread, coz that's listening on the socket for us. | ||
347 | ]] | ||
348 | end | ||
349 | |||
350 | -- Typecasting stuff. | ||
351 | |||
314 | function LSL.floatTypecast(x) | 352 | function LSL.floatTypecast(x) |
315 | local temp = tonumber(x) | 353 | local temp = tonumber(x) |
316 | if nil == temp then temp = 0 end | 354 | if nil == temp then temp = 0 end |
317 | return temp; | 355 | return temp; |
318 | end | 356 | end |
319 | 357 | ||
320 | function LSL.integerTypecast(x) | 358 | function LSL.integerTypecast(x) |
321 | local temp = tonumber(x) | 359 | local temp = tonumber(x) |
322 | if nil == temp then temp = 0 end | 360 | if nil == temp then temp = 0 end |
323 | return temp; | 361 | return temp; |
324 | end | 362 | end |
325 | 363 | ||
326 | function LSL.keyTypecast(x) | 364 | function LSL.keyTypecast(x) |
327 | return "" .. x; | 365 | return "" .. x; |
328 | end | 366 | end |
329 | 367 | ||
330 | function LSL.listTypecast(x) | 368 | function LSL.listTypecast(x) |
331 | return {x}; | 369 | return {x}; |
332 | end | 370 | end |
333 | 371 | ||
334 | function LSL.rotationTypecast(x) | 372 | function LSL.rotationTypecast(x) |
335 | return x; | 373 | return x; |
336 | end | 374 | end |
337 | 375 | ||
338 | function LSL.stringTypecast(x) | 376 | function LSL.stringTypecast(x) |
339 | return "" .. x; | 377 | return "" .. x; |
340 | end | 378 | end |
341 | 379 | ||
342 | function LSL.vectorTypecast(x) | 380 | function LSL.vectorTypecast(x) |
343 | return x; | 381 | return x; |
344 | end | 382 | end |
345 | 383 | ||
346 | return LSL; | ||
347 | 384 | ||
385 | return LSL; | ||
diff --git a/LuaSL/src/LuaSL_compile.c b/LuaSL/src/LuaSL_compile.c index 0a194a8..80eda62 100644 --- a/LuaSL/src/LuaSL_compile.c +++ b/LuaSL/src/LuaSL_compile.c | |||
@@ -1636,7 +1636,7 @@ static void outputRawStatement(FILE *file, outputMode mode, LSL_Statement *state | |||
1636 | } | 1636 | } |
1637 | else if (OM_LUA == mode) | 1637 | else if (OM_LUA == mode) |
1638 | { | 1638 | { |
1639 | fprintf(file, "_LSL.stateChange(_"); | 1639 | fprintf(file, "return _LSL.stateChange(_"); |
1640 | if (statement->identifier.text) | 1640 | if (statement->identifier.text) |
1641 | outputText(file, &(statement->identifier), TRUE); | 1641 | outputText(file, &(statement->identifier), TRUE); |
1642 | fprintf(file, "State)"); | 1642 | fprintf(file, "State)"); |
@@ -2277,7 +2277,7 @@ boolean compileLSL(gameGlobals *game, char *script, boolean doConstants) | |||
2277 | fprintf(out, "local _bit = require(\"bit\")\n"); | 2277 | fprintf(out, "local _bit = require(\"bit\")\n"); |
2278 | fprintf(out, "local _LSL = require(\"LSL\")\n\n"); | 2278 | fprintf(out, "local _LSL = require(\"LSL\")\n\n"); |
2279 | outputLeaf(out, OM_LUA, compiler.ast); | 2279 | outputLeaf(out, OM_LUA, compiler.ast); |
2280 | fprintf(out, "\n\n_LSL.stateChange(_defaultState)\n"); // This actually starts the script running. | 2280 | fprintf(out, "\n\n_LSL.mainLoop(_defaultState)\n"); // This actually starts the script running. |
2281 | fprintf(out, "\n--// End of generated code.\n\n"); | 2281 | fprintf(out, "\n--// End of generated code.\n\n"); |
2282 | fclose(out); | 2282 | fclose(out); |
2283 | 2283 | ||