#include <celx.h>
Collaboration diagram for LuaState:

Public Types | |
| enum | IOMode { NoIO = 1, Asking = 2, IOAllowed = 4, IODenied = 8 } |
Public Member Functions | |
| bool | charEntered (const char *) |
| void | cleanup () |
| bool | createThread () |
| std::string | getErrorMessage () |
| lua_State * | getState () const |
| double | getTime () const |
| bool | init (CelestiaCore *) |
| bool | isAlive () const |
| int | loadScript (const std::string &) |
| int | loadScript (std::istream &, const std::string &streamname) |
| LuaState () | |
| void | requestIO () |
| int | resume () |
| bool | tick (double) |
| bool | timesliceExpired () |
| ~LuaState () | |
Public Attributes | |
| int | screenshotCount |
| double | timeout |
Private Attributes | |
| bool | alive |
| lua_State * | costate |
| IOMode | ioMode |
| double | scriptAwakenTime |
| lua_State * | state |
| Timer * | timer |
|
|
Definition at line 53 of file celx.h.
|
|
|
Definition at line 372 of file celx.cpp. References CreateTimer(), MaxTimeslice, screenshotCount, state, and timer. 00372 : 00373 timeout(MaxTimeslice), 00374 state(NULL), 00375 costate(NULL), 00376 alive(false), 00377 timer(NULL), 00378 scriptAwakenTime(0.1), 00379 ioMode(NoIO) 00380 { 00381 state = lua_open(); 00382 timer = CreateTimer(); 00383 screenshotCount = 0; 00384 }
|
|
|
Definition at line 386 of file celx.cpp. References costate, state, and timer. 00387 {
00388 delete timer;
00389 if (state != NULL)
00390 lua_close(state);
00391 #if 0
00392 if (costate != NULL)
00393 lua_close(costate);
00394 #endif
00395 }
|
|
|
Definition at line 594 of file celx.cpp. References Asking, costate, getAppCore(), CelestiaCore::getRenderer(), CelestiaCore::getTextEnterMode(), getTime(), IOAllowed, IODenied, ioMode, KbdCallback, NoErrors, Renderer::setRenderFlags(), CelestiaCore::setTextEnterMode(), CelestiaCore::showText(), and timeout. 00595 {
00596 if (ioMode == Asking && getTime() > timeout)
00597 {
00598 int stackTop = lua_gettop(costate);
00599 if (strcmp(c_p, "y") == 0)
00600 {
00601 lua_iolibopen(costate);
00602 ioMode = IOAllowed;
00603 }
00604 else
00605 {
00606 ioMode = IODenied;
00607 }
00608 CelestiaCore* appCore = getAppCore(costate, NoErrors);
00609 if (appCore == NULL)
00610 {
00611 cerr << "ERROR: appCore not found\n";
00612 return true;
00613 }
00614 appCore->setTextEnterMode(appCore->getTextEnterMode() & ~CelestiaCore::KbPassToScript);
00615 appCore->showText("", 0, 0, 0, 0);
00616 // Restore renderflags:
00617 lua_pushstring(costate, "celestia-savedrenderflags");
00618 lua_gettable(costate, LUA_REGISTRYINDEX);
00619 if (lua_isuserdata(costate, -1))
00620 {
00621 int* savedrenderflags = static_cast<int*>(lua_touserdata(costate, -1));
00622 appCore->getRenderer()->setRenderFlags(*savedrenderflags);
00623 // now delete entry:
00624 lua_pushstring(costate, "celestia-savedrenderflags");
00625 lua_pushnil(costate);
00626 lua_settable(costate, LUA_REGISTRYINDEX);
00627 }
00628 else
00629 {
00630 cerr << "Oops, expected savedrenderflags to be userdata\n";
00631 }
00632 lua_settop(costate,stackTop);
00633 return true;
00634 }
00635 int stack_top = lua_gettop(costate);
00636 bool result = true;
00637 lua_pushstring(costate, KbdCallback);
00638 lua_gettable(costate, LUA_GLOBALSINDEX);
00639 lua_pushstring(costate, c_p);
00640 timeout = getTime() + 1.0;
00641 if (lua_pcall(costate, 1, 1, 0) != 0)
00642 {
00643 cerr << "Error while executing keyboard-callback: " << lua_tostring(costate, -1) << "\n";
00644 result = false;
00645 }
00646 else
00647 {
00648 if (lua_isboolean(costate, -1))
00649 {
00650 result = static_cast<bool>(lua_toboolean(costate, -1));
00651 }
00652 }
00653 // cleanup stack - is this necessary?
00654 lua_settop(costate, stack_top);
00655 return result;
00656 }
|
|
|
Definition at line 439 of file celx.cpp. References Asking, CleanupCallback, costate, getAppCore(), CelestiaCore::getRenderer(), getTime(), ioMode, NoErrors, Renderer::setRenderFlags(), state, and timeout. 00440 {
00441 if (ioMode == Asking)
00442 {
00443 // Restore renderflags:
00444 CelestiaCore* appCore = getAppCore(costate, NoErrors);
00445 if (appCore != NULL)
00446 {
00447 lua_pushstring(state, "celestia-savedrenderflags");
00448 lua_gettable(state, LUA_REGISTRYINDEX);
00449 if (lua_isuserdata(state, -1))
00450 {
00451 int* savedrenderflags = static_cast<int*>(lua_touserdata(state, -1));
00452 appCore->getRenderer()->setRenderFlags(*savedrenderflags);
00453 // now delete entry:
00454 lua_pushstring(state, "celestia-savedrenderflags");
00455 lua_pushnil(state);
00456 lua_settable(state, LUA_REGISTRYINDEX);
00457 }
00458 lua_pop(state,1);
00459 }
00460 }
00461 lua_pushstring(costate, CleanupCallback);
00462 lua_gettable(costate, LUA_GLOBALSINDEX);
00463 if (lua_isnil(costate, -1))
00464 {
00465 return;
00466 }
00467 timeout = getTime() + 1.0;
00468 if (lua_pcall(costate, 0, 0, 0) != 0)
00469 {
00470 cerr << "Error while executing cleanup-callback: " << lua_tostring(costate, -1) << "\n";
00471 }
00472 }
|
|
|
Definition at line 475 of file celx.cpp. References alive, checkTimeslice(), costate, and state. 00476 {
00477 // Initialize the coroutine which wraps the script
00478 if (!(lua_isfunction(state, -1) && !lua_iscfunction(state, -1)))
00479 {
00480 // Should never happen; we manually set up the stack in C++
00481 assert(0);
00482 return false;
00483 }
00484 else
00485 {
00486 costate = lua_newthread(state);
00487 if (costate == NULL)
00488 return false;
00489 lua_sethook(costate, checkTimeslice, LUA_MASKCOUNT, 1000);
00490 lua_pushvalue(state, -2);
00491 lua_xmove(state, costate, 1); /* move function from L to NL */
00492 alive = true;
00493 return true;
00494 }
00495 }
|
|
|
Definition at line 498 of file celx.cpp. References state. 00499 {
00500 if (lua_gettop(state) > 0)
00501 {
00502 if (lua_isstring(state, -1))
00503 return lua_tostring(state, -1);
00504 }
00505 return "";
00506 }
|
|
|
Definition at line 397 of file celx.cpp. References state. Referenced by tick(). 00398 {
00399 return state;
00400 }
|
|
|
Definition at line 403 of file celx.cpp. References Timer::getTime(), and timer. Referenced by celestia_getscripttime(), celestia_takescreenshot(), celscript_tick(), charEntered(), cleanup(), object_preloadtexture(), resume(), tick(), and timesliceExpired().
|
|
|
Definition at line 4575 of file celx.cpp. References alerter, celestia_new(), CreateCelestiaMetaTable(), CreateCelscriptMetaTable(), CreateFrameMetaTable(), CreateObjectMetaTable(), CreateObserverMetaTable(), CreatePositionMetaTable(), CreateRotationMetaTable(), CreateVectorMetaTable(), KdeAlerter::fatalError(), initMaps(), KM_PER_LY, loadScript(), and state. 04576 {
04577 initMaps();
04578
04579 // Import the base and math libraries
04580 lua_baselibopen(state);
04581 lua_mathlibopen(state);
04582 lua_tablibopen(state);
04583 lua_strlibopen(state);
04584
04585 // Add an easy to use wait function, so that script writers can
04586 // live in ignorance of coroutines. There will probably be a significant
04587 // library of useful functions that can be defined purely in Lua.
04588 // At that point, we'll want something a bit more robust than just
04589 // parsing the whole text of the library every time a script is launched
04590 if (loadScript("wait = function(x) coroutine.yield(x) end") != 0)
04591 return false;
04592 lua_pcall(state, 0, 0, 0); // execute it
04593
04594 lua_pushstring(state, "KM_PER_MICROLY");
04595 lua_pushnumber(state, (lua_Number)KM_PER_LY/1e6);
04596 lua_settable(state, LUA_GLOBALSINDEX);
04597
04598 CreateObjectMetaTable(state);
04599 CreateObserverMetaTable(state);
04600 CreateCelestiaMetaTable(state);
04601 CreatePositionMetaTable(state);
04602 CreateVectorMetaTable(state);
04603 CreateRotationMetaTable(state);
04604 CreateFrameMetaTable(state);
04605 CreateCelscriptMetaTable(state);
04606
04607 // Create the celestia object
04608 lua_pushstring(state, "celestia");
04609 celestia_new(state, appCore);
04610 lua_settable(state, LUA_GLOBALSINDEX);
04611 // add reference to appCore in the registry
04612 lua_pushstring(state, "celestia-appcore");
04613 lua_pushlightuserdata(state, static_cast<void*>(appCore));
04614 lua_settable(state, LUA_REGISTRYINDEX);
04615 // add a reference to the LuaState-object in the registry
04616 lua_pushstring(state, "celestia-luastate");
04617 lua_pushlightuserdata(state, static_cast<void*>(this));
04618 lua_settable(state, LUA_REGISTRYINDEX);
04619
04620 #if 0
04621 lua_pushstring(state, "dofile");
04622 lua_gettable(state, LUA_GLOBALSINDEX); // function "dofile" on stack
04623 lua_pushstring(state, "luainit.celx"); // parameter
04624 if (lua_pcall(state, 1, 0, 0) != 0) // execute it
04625 {
04626 CelestiaCore::Alerter* alerter = appCore->getAlerter();
04627 // copy string?!
04628 const char* errorMessage = lua_tostring(state, -1);
04629 cout << errorMessage << '\n'; cout.flush();
04630 alerter->fatalError(errorMessage);
04631 return false;
04632 }
04633 #endif
04634
04635 return true;
04636 }
|
|
|
Definition at line 552 of file celx.cpp. References alive. Referenced by tick(). 00553 {
00554 return alive;
00555 }
|
|
|
Definition at line 681 of file celx.cpp. References loadScript(). 00682 {
00683 #ifdef HAVE_SSTREAM
00684 istringstream in(s);
00685 #else
00686 istrstream in(s.c_str());
00687 #endif
00688 return loadScript(in, "string");
00689 }
|
|
||||||||||||
|
Definition at line 659 of file celx.cpp. References ReadChunkInfo::buf, ReadChunkInfo::bufSize, ReadChunkInfo::in, readStreamChunk(), and state. Referenced by init(), and loadScript(). 00660 {
00661 char buf[4096];
00662 ReadChunkInfo info;
00663 info.buf = buf;
00664 info.bufSize = sizeof(buf);
00665 info.in = ∈
00666
00667 if (streamname != "string")
00668 {
00669 lua_pushstring(state, "celestia-scriptpath");
00670 lua_pushstring(state, streamname.c_str());
00671 lua_settable(state, LUA_REGISTRYINDEX);
00672 }
00673
00674 int status = lua_load(state, readStreamChunk, &info, streamname.c_str());
00675 if (status != 0)
00676 cout << "Error loading script: " << lua_tostring(state, -1) << '\n';
00677
00678 return status;
00679 }
|
|
|
Definition at line 852 of file celx.cpp. References AllErrors, Asking, costate, getAppCore(), CelestiaCore::getConfig(), IOAllowed, IODenied, ioMode, NoIO, CelestiaConfig::scriptSystemAccessPolicy, and state. Referenced by celestia_requestsystemaccess(). 00853 {
00854 // the script requested IO, set the mode
00855 // so we display the warning during tick
00856 // and can request keyboard. We can't do this now
00857 // because the script is still active and could
00858 // disable keyboard again.
00859 if (ioMode == NoIO)
00860 {
00861 CelestiaCore* appCore = getAppCore(state, AllErrors);
00862 string policy = appCore->getConfig()->scriptSystemAccessPolicy;
00863 if (policy == "allow")
00864 {
00865 //lua_iolibopen(costate);
00866 luaopen_io(costate);
00867 ioMode = IOAllowed;
00868 }
00869 else if (policy == "deny")
00870 {
00871 ioMode = IODenied;
00872 }
00873 else
00874 {
00875 ioMode = Asking;
00876 }
00877 }
00878 }
|
|
|
Definition at line 691 of file celx.cpp. References alerter, alive, Asking, auxresume(), costate, KdeAlerter::fatalError(), CelestiaCore::getAlerter(), getAppCore(), getTime(), ioMode, MaxTimeslice, state, and timeout. Referenced by tick(). 00692 {
00693 assert(costate != NULL);
00694 if (costate == NULL)
00695 return false;
00696
00697 lua_State* co = lua_tothread(state, -1);
00698 //assert(co == costate); // co can be NULL after error (top stack is errorstring)
00699 if (co != costate)
00700 return false;
00701
00702 timeout = getTime() + MaxTimeslice;
00703 int nArgs = auxresume(state, co, 0);
00704 if (nArgs < 0)
00705 {
00706 alive = false;
00707
00708 const char* errorMessage = lua_tostring(state, -1);
00709
00710 // This is a nasty and hopefully temporary hack . . . We continue
00711 // to resume the script until we get an error. The
00712 // 'cannot resume dead coroutine' error appears when there were
00713 // no other errors, and execution terminates normally. There
00714 // should be a better way to figure out whether the script ended
00715 // normally . . .
00716 if (strcmp(errorMessage, "cannot resume dead coroutine") != 0)
00717 {
00718 cout << "Error: " << errorMessage << '\n';
00719 CelestiaCore* appCore = getAppCore(co);
00720 if (appCore != NULL)
00721 {
00722 CelestiaCore::Alerter* alerter = appCore->getAlerter();
00723 alerter->fatalError(errorMessage);
00724 }
00725 }
00726
00727 return 1; // just the error string
00728 }
00729 else
00730 {
00731 if (ioMode == Asking)
00732 {
00733 // timeout now is used to first only display warning, and 1s
00734 // later allow response to avoid accidental activation
00735 timeout = getTime() + 1.0;
00736 }
00737
00738 return nArgs; // arguments from yield
00739 }
00740 }
|
|
|
Definition at line 763 of file celx.cpp. References Asking, costate, getAppCore(), CelestiaCore::getRenderer(), Renderer::getRenderFlags(), getState(), CelestiaCore::getTextEnterMode(), getTime(), ioMode, isAlive(), NoErrors, resume(), scriptAwakenTime, Renderer::setRenderFlags(), CelestiaCore::setTextEnterMode(), CelestiaCore::showText(), state, and timeout. 00764 {
00765 // Due to the way CelestiaCore::tick is called (at least for KDE),
00766 // this method may be entered a second time when we show the error-alerter
00767 // Workaround: check if we are alive, return true(!) when we aren't anymore
00768 // this way the script isn't deleted after the second enter, but only
00769 // when we return from the first enter. OMG.
00770
00771 // better Solution: defer showing the error-alterter to CelestiaCore, using
00772 // getErrorMessage()
00773 if (!isAlive())
00774 return false;
00775
00776 if (ioMode == Asking)
00777 {
00778 CelestiaCore* appCore = getAppCore(costate, NoErrors);
00779 if (appCore == NULL)
00780 {
00781 cerr << "ERROR: appCore not found\n";
00782 return true;
00783 }
00784 lua_pushstring(state, "celestia-savedrenderflags");
00785 lua_gettable(state, LUA_REGISTRYINDEX);
00786 if (lua_isnil(state, -1))
00787 {
00788 lua_pushstring(state, "celestia-savedrenderflags");
00789 int* savedrenderflags = static_cast<int*>(lua_newuserdata(state, sizeof(int)));
00790 *savedrenderflags = appCore->getRenderer()->getRenderFlags();
00791 lua_settable(state, LUA_REGISTRYINDEX);
00792 appCore->getRenderer()->setRenderFlags(0);
00793 }
00794 // now pop result of gettable
00795 lua_pop(state, 1);
00796
00797 if (getTime() > timeout)
00798 {
00799 appCore->showText("WARNING:\n\nThis script requests permission to read/write files\n"
00800 "and execute external programs. Allowing this can be\n"
00801 "dangerous.\n"
00802 "Do you trust the script and want to allow this?\n\n"
00803 "y = yes, ESC = cancel script, any other key = no",
00804 0, 0,
00805 -15, 5, 5);
00806 appCore->setTextEnterMode(appCore->getTextEnterMode() | CelestiaCore::KbPassToScript);
00807 }
00808 else
00809 {
00810 appCore->showText("WARNING:\n\nThis script requests permission to read/write files\n"
00811 "and execute external programs. Allowing this can be\n"
00812 "dangerous.\n"
00813 "Do you trust the script and want to allow this?",
00814 0, 0,
00815 -15, 5, 5);
00816 appCore->setTextEnterMode(appCore->getTextEnterMode() & ~CelestiaCore::KbPassToScript);
00817 }
00818
00819 return false;
00820 }
00821
00822 if (dt == 0 || scriptAwakenTime > getTime())
00823 return false;
00824
00825 int nArgs = resume();
00826 if (!isAlive())
00827 {
00828 // The script is complete
00829 return true;
00830 }
00831 else
00832 {
00833 // The script has returned control to us, but it is not completed.
00834 lua_State* state = getState();
00835
00836 // The values on the stack indicate what event will wake up the
00837 // script. For now, we just support wait()
00838 double delay;
00839 if (nArgs == 1 && lua_isnumber(state, -1))
00840 delay = lua_tonumber(state, -1);
00841 else
00842 delay = 0.0;
00843 scriptAwakenTime = getTime() + delay;
00844
00845 // Clean up the stack
00846 lua_pop(state, nArgs);
00847 return false;
00848 }
00849 }
|
|
|
Definition at line 509 of file celx.cpp. References checkTimeslice(), costate, getTime(), and timeout. Referenced by checkTimeslice(). 00510 {
00511 if (timeout < getTime())
00512 {
00513 // timeslice expired, make every instruction (including pcall) fail:
00514 lua_sethook(costate, checkTimeslice, LUA_MASKCOUNT, 1);
00515 return true;
00516 }
00517 else
00518 {
00519 return false;
00520 }
00521 }
|
|
|
Definition at line 63 of file celx.h. Referenced by createThread(), isAlive(), and resume(). |
|
|
Definition at line 62 of file celx.h. Referenced by charEntered(), cleanup(), createThread(), requestIO(), resume(), tick(), timesliceExpired(), and ~LuaState(). |
|
|
Definition at line 66 of file celx.h. Referenced by charEntered(), cleanup(), requestIO(), resume(), and tick(). |
|
|
Definition at line 50 of file celx.h. Referenced by celestia_takescreenshot(), and LuaState(). |
|
|
Definition at line 65 of file celx.h. Referenced by tick(). |
|
|
Definition at line 61 of file celx.h. Referenced by cleanup(), createThread(), getErrorMessage(), getState(), init(), loadScript(), LuaState(), requestIO(), resume(), tick(), and ~LuaState(). |
|
|
Definition at line 51 of file celx.h. Referenced by celestia_takescreenshot(), charEntered(), cleanup(), object_preloadtexture(), resume(), tick(), and timesliceExpired(). |
|
|
Definition at line 64 of file celx.h. Referenced by getTime(), LuaState(), and ~LuaState(). |
1.4.1