aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ClientHamr/GuiLua/GuiLua.c
diff options
context:
space:
mode:
Diffstat (limited to 'ClientHamr/GuiLua/GuiLua.c')
-rw-r--r--ClientHamr/GuiLua/GuiLua.c90
1 files changed, 41 insertions, 49 deletions
diff --git a/ClientHamr/GuiLua/GuiLua.c b/ClientHamr/GuiLua/GuiLua.c
index ac156ed..c463eca 100644
--- a/ClientHamr/GuiLua/GuiLua.c
+++ b/ClientHamr/GuiLua/GuiLua.c
@@ -142,10 +142,9 @@ and ordinary elementary widgets. Proper introspection can come later.
142 142
143#include "GuiLua.h" 143#include "GuiLua.h"
144 144
145globals ourGlobals;
146 145
147static const char *ourName = "widget"; 146globals ourGlobals;
148static int skang, _M; 147static const char *globName = "ourGlobals";
149 148
150 149
151void dumpStack(lua_State *L, int i) 150void dumpStack(lua_State *L, int i)
@@ -255,6 +254,7 @@ char *getDateTime(struct tm **nowOut, char *dateOut, time_t *timeOut)
255// ( Just syntax sugar for call. 254// ( Just syntax sugar for call.
256// call ) Expects an integer, the number of results left after the call. 255// call ) Expects an integer, the number of results left after the call.
257// FIXME: Still to do, if we ever use them - 256// FIXME: Still to do, if we ever use them -
257// stack = Get a value from the stack, expects a stack index.
258// userdata + 258// userdata +
259// lightuserdata * 259// lightuserdata *
260// thread ^ 260// thread ^
@@ -445,6 +445,12 @@ int push_lua(lua_State *L, char *params, ...) // Stack usage [-0, +n, em]
445 lua_pushboolean(L, va_arg(vl, int)); // Stack usage [-0, +1, -] 445 lua_pushboolean(L, va_arg(vl, int)); // Stack usage [-0, +1, -]
446 break; 446 break;
447 } 447 }
448 case '=':
449 {
450 if (table) q = _push_name(L, q, &i); // Stack usage [-0, +1, m]
451 lua_pushvalue(L, va_arg(vl, int)); // Stack usage [-0, +1, -]
452 break;
453 }
448 case '@': 454 case '@':
449 { 455 {
450 int tabl = va_arg(vl, int); 456 int tabl = va_arg(vl, int);
@@ -528,7 +534,7 @@ static int window(lua_State *L)
528 char *title = NULL; 534 char *title = NULL;
529 int w = WIDTH, h = HEIGHT; 535 int w = WIDTH, h = HEIGHT;
530 536
531 lua_getfield(L, LUA_REGISTRYINDEX, "ourGlobals"); 537 lua_getfield(L, LUA_REGISTRYINDEX, globName);
532 ourGlobals = lua_touserdata(L, -1); 538 ourGlobals = lua_touserdata(L, -1);
533 lua_pop(L, 1); 539 lua_pop(L, 1);
534 540
@@ -552,7 +558,7 @@ static int loopWindow(lua_State *L)
552{ 558{
553 globals *ourGlobals; 559 globals *ourGlobals;
554 560
555 lua_getfield(L, LUA_REGISTRYINDEX, "ourGlobals"); 561 lua_getfield(L, LUA_REGISTRYINDEX, globName);
556 ourGlobals = lua_touserdata(L, -1); 562 ourGlobals = lua_touserdata(L, -1);
557 lua_pop(L, 1); 563 lua_pop(L, 1);
558 564
@@ -566,7 +572,7 @@ static int closeWindow(lua_State *L)
566{ 572{
567 globals *ourGlobals; 573 globals *ourGlobals;
568 574
569 lua_getfield(L, LUA_REGISTRYINDEX, "ourGlobals"); 575 lua_getfield(L, LUA_REGISTRYINDEX, globName);
570 ourGlobals = lua_touserdata(L, -1); 576 ourGlobals = lua_touserdata(L, -1);
571 lua_pop(L, 1); 577 lua_pop(L, 1);
572 578
@@ -584,72 +590,59 @@ static int closeWindow(lua_State *L)
584 return 0; 590 return 0;
585} 591}
586 592
587/* local widget = require 'widget' 593/* local widget = require 'libGuiLua'
588 594
589Lua's require() function will strip any stuff from the front of the name 595Lua's require() function will strip any stuff from the front of the name
590separated by a hyphen, so 'ClientHamr-GuiLua-widget' -> 'widget'. Then 596separated by a hyphen, so 'ClientHamr-GuiLua-libGuiLua' -> 'libGuiLua'. Then
591it will search through a path, and eventually find this widget.so (or 597it will search through a path, and eventually find this libGuiLua.so (or
592widget.dll or whatever), then call luaopen_widget(), which should return 598libGuiLua.dll or whatever), then call luaopen_libGuiLua(), which should return
593a table. The argument (only thing on the stack) for this function will 599a table. The argument (only thing on the stack) for this function will
594be 'widget'. 600be 'libGuiLua'.
595 601
596Normally luaL_register() creates a table of functions, that is the table 602Normally luaL_register() creates a table of functions, that is the table
597returned, but we want to do something different with skang. 603returned, but we want to do something different with skang.
598*/ 604*/
599int luaopen_widget(lua_State *L) 605int luaopen_libGuiLua(lua_State *L)
600{ 606{
601 // In theory, the only thing on the stack now is 'widget' from the require() call. 607 int skang;
602 608
603 // In theory this function only ever gets called once. 609 // In theory this function only ever gets called once.
604 memset(&ourGlobals, 0, sizeof(globals)); 610 memset(&ourGlobals, 0, sizeof(globals));
605 loggingStartup(&ourGlobals); 611 loggingStartup(&ourGlobals);
606 612
607 // Shove ourGlobals into the registry.
608 lua_pushlightuserdata(L, &ourGlobals);
609 lua_setfield(L, LUA_REGISTRYINDEX, "ourGlobals");
610
611// pseudo-indices, special tables that can be accessed like the stack - 613// pseudo-indices, special tables that can be accessed like the stack -
612// LUA_GLOBALSINDEX - thread environment, where globals are 614// LUA_GLOBALSINDEX - thread environment, where globals are
613// LUA_ENVIRONINDEX - C function environment, in this case luaopen_widget() is the C function 615// LUA_ENVIRONINDEX - C function environment, in this case luaopen_widget() is the C function
614// LUA_REGISTRYINDEX - C registry, global, for unique keys use the module name as a string, or a lightuserdata address to a C object in our module. 616// LUA_REGISTRYINDEX - C registry, global, for unique keys use the module name as a string, or a lightuserdata address to a C object in our module.
615// lua_upvalueindex(n) - C function upvalues 617// lua_upvalueindex(n) - C function upvalues
616 618
617// The only locals we care about are skang and _M. 619 // Shove ourGlobals into the registry.
618// All modules go into package.loaded[name] as well. 620 lua_pushlightuserdata(L, &ourGlobals);
619// skang is essentially a global anyway. 621 lua_setfield(L, LUA_REGISTRYINDEX, globName);
620// _M we pass back as the result, and our functions get added to it by skang.thingasm() 622
621// Not entirely true, _M is a proxy table, getmetatable(_M).__values[cfunc] would be our function. 623 // The skang module should have been loaded by now, so we can just grab it out of package.loaded[].
622 624 lua_getglobal(L, "package");
623// local skang = require 'skang' 625 lua_getfield(L, lua_gettop(L), "loaded");
624 lua_getglobal(L, "require"); 626 lua_remove(L, -2); // Removes "package"
625 lua_pushstring(L, "skang"); 627 lua_getfield(L, lua_gettop(L), SKANG);
626 lua_call(L, 1, 1); 628 lua_remove(L, -2); // Removes "loaded"
629 lua_setfield(L, LUA_REGISTRYINDEX, SKANG);
630 lua_getfield(L, LUA_REGISTRYINDEX, SKANG); // Puts the skang table back on the stack.
627 skang = lua_gettop(L); 631 skang = lua_gettop(L);
628 632
629 lua_setfield(L, LUA_REGISTRYINDEX, "skang");
630 lua_getfield(L, LUA_REGISTRYINDEX, "skang");
631
632// local _M = skang.moduleBegin('widget', nil, 'Copyright 2014 David Seikel', '0.1', '2014-04-08 00:42:00', nil, false)
633 push_lua(L, "@ ( $ ~ $ $ $ ~ ! )", skang, "moduleBegin", ourName, "Copyright 2014 David Seikel", "0.1", "2014-04-08 00:42:00", 0, 1);
634 _M = lua_gettop(L);
635
636 // Save this module in the C registry.
637 lua_setfield(L, LUA_REGISTRYINDEX, ourName);
638 lua_getfield(L, LUA_REGISTRYINDEX, ourName);
639
640 // Define our functions. 633 // Define our functions.
641 push_lua(L, "@ ( @ $ $ & $ )", skang, "thingasm", LUA_REGISTRYINDEX, ourName, "window", "Opens our window.", window, "number,number,string", 0); 634 push_lua(L, "@ ( = $ $ & $ )", skang, THINGASM, skang, "window", "Opens our window.", window, "number,number,string", 0);
642 push_lua(L, "@ ( @ $ $ & )", skang, "thingasm", LUA_REGISTRYINDEX, ourName, "loopWindow", "Run our windows main loop.", loopWindow, 0); 635 push_lua(L, "@ ( = $ $ & )", skang, THINGASM, skang, "loopWindow", "Run our windows main loop.", loopWindow, 0);
643 push_lua(L, "@ ( @ $ $ & )", skang, "thingasm", LUA_REGISTRYINDEX, ourName, "closeWindow", "Closes our window.", closeWindow, 0); 636 push_lua(L, "@ ( = $ $ & )", skang, THINGASM, skang, "closeWindow", "Closes our window.", closeWindow, 0);
644 637
645 // A test of the array building stuff. 638 // A test of the array building stuff.
646 push_lua(L, "@ ( { @ $ $ % $widget !required } )", skang, "thingasm", LUA_REGISTRYINDEX, ourName, "wibble", "It's wibbly!", 1, "'edit', 'The wibblinator:', 1, 1, 10, 50", 1, 0); 639 push_lua(L, "@ ( { = $ $ % $widget !required } )", skang, THINGASM, skang, "wibble", "It's wibbly!", 1, "'edit', 'The wibblinator:', 1, 1, 10, 50", 1, 0);
647
648 push_lua(L, "@ ( @ )", skang, "moduleEnd", LUA_REGISTRYINDEX, ourName, 0);
649 640
641 // Makes no difference what we return, but it's expecting something.
650 return 1; 642 return 1;
651} 643}
652 644
645
653void GuiLuaDo(int argc, char **argv) 646void GuiLuaDo(int argc, char **argv)
654{ 647{
655 lua_State *L; 648 lua_State *L;
@@ -672,13 +665,12 @@ void GuiLuaDo(int argc, char **argv)
672 lua_setfield(L, LUA_GLOBALSINDEX, "arg"); 665 lua_setfield(L, LUA_GLOBALSINDEX, "arg");
673 666
674 667
675 lua_getglobal(L, "require");
676 lua_pushstring(L, "skang");
677 // When we do this, skang will process all the arguments passed to GuiLuaDo(). 668 // When we do this, skang will process all the arguments passed to GuiLuaDo().
678 // This likely includes a module load, which likely loads the widget module above. 669 // This likely includes a module load, which likely opens a window.
670 lua_getglobal(L, "require");
671 lua_pushstring(L, SKANG);
679 lua_call(L, 1, 1); 672 lua_call(L, 1, 1);
680 skang = lua_gettop(L); 673 lua_pop(L, 1); // Ignore the returned value.
681 lua_setfield(L, LUA_REGISTRYINDEX, "skang");
682 674
683 675
684 // Run the main loop via a Lua call. 676 // Run the main loop via a Lua call.