aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/LuaSL/src
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-02-05 15:38:46 +1000
committerDavid Walter Seikel2012-02-05 15:38:46 +1000
commit4c45884e658800a2528381cb1368514499d592d8 (patch)
tree588b8f4ea1e45cd02c84eb2ee3178dc1bb7f7458 /LuaSL/src
parentCommentry. (diff)
downloadSledjHamr-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.lua74
-rw-r--r--LuaSL/src/LuaSL_compile.c4
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
22the same module loaded simultaneously. To address this, one may instead 22the same module loaded simultaneously. To address this, one may instead
23use a lightuserdata (pointer to variable of static linkage to ensure 23use a lightuserdata (pointer to variable of static linkage to ensure
24global uniqueness) for this key or store the metatable as an 24global uniqueness) for this key or store the metatable as an
25upvalue--either way is a bit more efficient and less error prone. 25upvalue--either way is a bit more efficient and less error prone.
26]] 26]]
27 27
28local LSL = {}; 28local LSL = {};
29 29
30-- LSL constants.
31
30LSL.PI = 3.14159265358979323846264338327950; 32LSL.PI = 3.14159265358979323846264338327950;
31LSL.PI_BY_TWO = LSL.PI / 2; -- 1.57079632679489661923132169163975 33LSL.PI_BY_TWO = LSL.PI / 2; -- 1.57079632679489661923132169163975
32LSL.TWO_PI = LSL.PI * 2; -- 6.28318530717958647692528676655900 34LSL.TWO_PI = LSL.PI * 2; -- 6.28318530717958647692528676655900
@@ -196,7 +198,7 @@ LSL.x = 0.0;
196LSL.y = 0.0; 198LSL.y = 0.0;
197LSL.z = 0.0; 199LSL.z = 0.0;
198 200
199-- Functions. 201-- ll*() functions.
200 202
201function --[[float]] LSL.llPow(--[[float]] number,--[[float]] places) return 0.0 end; 203function --[[float]] LSL.llPow(--[[float]] number,--[[float]] places) return 0.0 end;
202function --[[float]] LSL.llFrand(--[[float]] max) return 0.0 end; 204function --[[float]] LSL.llFrand(--[[float]] max) return 0.0 end;
@@ -295,53 +297,89 @@ function LSL.llWhisper(--[[integer]] channel, --[[string]] text) print("Channe
295 297
296function LSL.llMessageLinked(--[[integer]] link,--[[integer]] num, --[[string]] text, --[[key]] aKey) end; 298function LSL.llMessageLinked(--[[integer]] link,--[[integer]] num, --[[string]] text, --[[key]] aKey) end;
297 299
300-- Crements stuff.
301
298function LSL.preDecrement(name) _G[name] = _G[name] - 1; return _G[name]; end; 302function LSL.preDecrement(name) _G[name] = _G[name] - 1; return _G[name]; end;
299function LSL.preIncrement(name) _G[name] = _G[name] + 1; return _G[name]; end; 303function LSL.preIncrement(name) _G[name] = _G[name] + 1; return _G[name]; end;
300function LSL.postDecrement(name) local temp = _G[name]; _G[name] = _G[name] - 1; return temp; end; 304function LSL.postDecrement(name) local temp = _G[name]; _G[name] = _G[name] - 1; return temp; end;
301function LSL.postIncrement(name) local temp = _G[name]; _G[name] = _G[name] + 1; return temp; end; 305function LSL.postIncrement(name) local temp = _G[name]; _G[name] = _G[name] + 1; return temp; end;
302 306
307-- State stuff
308
303local currentState = {} 309local currentState = {}
310
304function LSL.stateChange(x) 311function 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
312end; 336end;
313 337
338function 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 ]]
348end
349
350-- Typecasting stuff.
351
314function LSL.floatTypecast(x) 352function 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;
318end 356end
319 357
320function LSL.integerTypecast(x) 358function 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;
324end 362end
325 363
326function LSL.keyTypecast(x) 364function LSL.keyTypecast(x)
327 return "" .. x; 365 return "" .. x;
328end 366end
329 367
330function LSL.listTypecast(x) 368function LSL.listTypecast(x)
331 return {x}; 369 return {x};
332end 370end
333 371
334function LSL.rotationTypecast(x) 372function LSL.rotationTypecast(x)
335 return x; 373 return x;
336end 374end
337 375
338function LSL.stringTypecast(x) 376function LSL.stringTypecast(x)
339 return "" .. x; 377 return "" .. x;
340end 378end
341 379
342function LSL.vectorTypecast(x) 380function LSL.vectorTypecast(x)
343 return x; 381 return x;
344end 382end
345 383
346return LSL;
347 384
385return 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