fixed a bug where events scheduled for the same time run in backwards order

simplified CoreTiming::AddEventToQueue
fixed emu.frameadvance and implemented emu.wait
fixed Lua script termination
brought over some luaconf customizations to fix issue 2245 in a better way and deal with certain other scripting problems

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5383 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
nitsuja- 2010-04-18 08:28:52 +00:00
parent 766818baa8
commit b31042cb10
6 changed files with 92 additions and 92 deletions

View File

@ -93,9 +93,9 @@
#define LUA_CDIR "!\\" #define LUA_CDIR "!\\"
#define LUA_PATH_DEFAULT \ #define LUA_PATH_DEFAULT \
".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" "?;" "?.lua"
#define LUA_CPATH_DEFAULT \ #define LUA_CPATH_DEFAULT \
".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" "?;" "?.dll"
#else #else
#define LUA_ROOT "/usr/local/" #define LUA_ROOT "/usr/local/"
@ -211,7 +211,7 @@
@* of a function in debug information. @* of a function in debug information.
** CHANGE it if you want a different size. ** CHANGE it if you want a different size.
*/ */
#define LUA_IDSIZE 60 #define LUA_IDSIZE 48
/* /*
@ -303,7 +303,7 @@
** mean larger pauses which mean slower collection.) You can also change ** mean larger pauses which mean slower collection.) You can also change
** this value dynamically. ** this value dynamically.
*/ */
#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ #define LUAI_GCPAUSE 150 /* 200% (wait memory to double before next GC) */
/* /*
@ -314,7 +314,7 @@
** infinity, where each step performs a full collection.) You can also ** infinity, where each step performs a full collection.) You can also
** change this value dynamically. ** change this value dynamically.
*/ */
#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ #define LUAI_GCMUL 150 /* GC runs 'twice the speed' of memory allocation */
@ -378,6 +378,9 @@
** a bit, but may be quite useful when debugging C code that interfaces ** a bit, but may be quite useful when debugging C code that interfaces
** with Lua. A useful redefinition is to use assert.h. ** with Lua. A useful redefinition is to use assert.h.
*/ */
#if defined(_DEBUG) || defined(DEBUGFAST)
#define LUA_USE_APICHECK
#endif
#if defined(LUA_USE_APICHECK) #if defined(LUA_USE_APICHECK)
#include <assert.h> #include <assert.h>
#define luai_apicheck(L,o) { (void)L; assert(o); } #define luai_apicheck(L,o) { (void)L; assert(o); }
@ -562,7 +565,7 @@
(defined(__i386) || defined (_M_IX86) || defined(__i386__)) (defined(__i386) || defined (_M_IX86) || defined(__i386__))
/* On a Microsoft compiler, use assembler */ /* On a Microsoft compiler, use assembler */
#if defined(_MSC_VER) #if 0 /*defined(_MSC_VER)*/ /* disabled because it handles some integers very incorrectly and the other case works perfectly fine with current MSVC compilers */
#define lua_number2int(i,d) __asm fld d __asm fistp i #define lua_number2int(i,d) __asm fld d __asm fistp i
#define lua_number2integer(i,n) lua_number2int(i, n) #define lua_number2integer(i,n) lua_number2int(i, n)

View File

@ -49,6 +49,7 @@ typedef LinkedListItem<BaseEvent> Event;
// STATE_TO_SAVE (how?) // STATE_TO_SAVE (how?)
Event *first; Event *first;
Event *tsFirst; Event *tsFirst;
Event *tsLast;
// event pools // event pools
Event *eventPool = 0; Event *eventPool = 0;
@ -213,9 +214,13 @@ void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata
Event *ne = GetNewTsEvent(); Event *ne = GetNewTsEvent();
ne->time = globalTimer + cyclesIntoFuture; ne->time = globalTimer + cyclesIntoFuture;
ne->type = event_type; ne->type = event_type;
ne->next = tsFirst; ne->next = 0;
ne->userdata = userdata; ne->userdata = userdata;
tsFirst = ne; if(!tsFirst)
tsFirst = ne;
if(tsLast)
tsLast->next = ne;
tsLast = ne;
externalEventSection.Leave(); externalEventSection.Leave();
} }
@ -243,44 +248,21 @@ void ClearPendingEvents()
} }
} }
void AddEventToQueue(Event *ne) void AddEventToQueue(Event* ne)
{ {
// Damn, this logic got complicated. Must be an easier way. Event* prev = NULL;
if (!first) Event** pNext = &first;
for(;;)
{ {
first = ne; Event*& next = *pNext;
ne->next = 0; if(!next || ne->time < next->time)
}
else
{
Event *ptr = first;
Event *prev = 0;
if (ptr->time > ne->time)
{ {
ne->next = first; ne->next = next;
first = ne; next = ne;
} break;
else
{
prev = first;
ptr = first->next;
while (ptr)
{
if (ptr->time <= ne->time)
{
prev = ptr;
ptr = ptr->next;
}
else
break;
}
//OK, ptr points to the item AFTER our new item. Let's insert
ne->next = prev->next;
prev->next = ne;
// Done!
} }
prev = next;
pNext = &prev->next;
} }
} }
@ -365,6 +347,7 @@ void Advance()
AddEventToQueue(tsFirst); AddEventToQueue(tsFirst);
tsFirst = next; tsFirst = next;
} }
tsLast = NULL;
// Move free events to threadsafe pool // Move free events to threadsafe pool
while(allocatedTsEvents > 0 && eventPool) while(allocatedTsEvents > 0 && eventPool)
@ -378,8 +361,8 @@ void Advance()
externalEventSection.Leave(); externalEventSection.Leave();
int cyclesExecuted = slicelength - downcount; int cyclesExecuted = slicelength - downcount;
globalTimer += cyclesExecuted; globalTimer += cyclesExecuted;
downcount = slicelength;
while (first) while (first)
{ {
@ -387,10 +370,10 @@ void Advance()
{ {
// LOG(GEKKO, "[Scheduler] %s (%lld, %lld) ", // LOG(GEKKO, "[Scheduler] %s (%lld, %lld) ",
// first->name ? first->name : "?", (u64)globalTimer, (u64)first->time); // first->name ? first->name : "?", (u64)globalTimer, (u64)first->time);
event_types[first->type].callback(first->userdata, (int)(globalTimer - first->time)); Event* evt = first;
Event *next = first->next; first = first->next;
FreeEvent(first); event_types[evt->type].callback(evt->userdata, (int)(globalTimer - evt->time));
first = next; FreeEvent(evt);
} }
else else
{ {

View File

@ -30,7 +30,8 @@
#include "PluginManager.h" #include "PluginManager.h"
#include "HW/Memmap.h" #include "HW/Memmap.h"
#include "Host.h" #include "Host.h"
#include "PowerPC/PowerPC.h"
#include "CoreTiming.h"
extern "C" { extern "C" {
#include "lua.h" #include "lua.h"
@ -1107,20 +1108,11 @@ DEFINE_LUA_FUNCTION(bitbit, "whichbit")
// (e.g. a savestate could possibly get loaded before emu.wait() returns) // (e.g. a savestate could possibly get loaded before emu.wait() returns)
DEFINE_LUA_FUNCTION(emulua_wait, "") DEFINE_LUA_FUNCTION(emulua_wait, "")
{ {
/*LuaContextInfo& info = GetCurrentInfo(); //LuaContextInfo& info = GetCurrentInfo();
switch(info.speedMode) // we're only calling this to run user events. (a windows-only example of what that means is the canonical Peek/Translate/Dispatch loop)
{ // hopefully this won't actually advance the emulation state in any non-user-input-driven way when called in this context...
default: CoreTiming::Advance();
case SPEEDMODE_NORMAL:
Step_emulua_MainLoop(true, false);
break;
case SPEEDMODE_NOTHROTTLE:
case SPEEDMODE_TURBO:
case SPEEDMODE_MAXIMUM:
Step_emulua_MainLoop(Core::GetState() == Core::CORE_PAUSE, false);
break;
}*/
return 0; return 0;
} }
@ -1176,6 +1168,7 @@ void LuaRescueHook(lua_State* L, lua_Debug *dbg)
{ {
//lua_sethook(L, NULL, 0, 0); //lua_sethook(L, NULL, 0, 0);
assert(L->errfunc || L->errorJmp); assert(L->errfunc || L->errorJmp);
luaL_error(L, info.panic ? info.panicMessage : "terminated by user");
} }
info.panic = false; info.panic = false;
@ -1213,7 +1206,7 @@ void printfToOutput(const char* fmt, ...)
bool FailVerifyAtFrameBoundary(lua_State* L, const char* funcName, int unstartedSeverity=2, int inframeSeverity=2) bool FailVerifyAtFrameBoundary(lua_State* L, const char* funcName, int unstartedSeverity=2, int inframeSeverity=2)
{ {
if (!Core::isRunning()) if (!Core::isRunning() || Core::GetState() == Core::CORE_STOPPING)
{ {
static const char* msg = "cannot call %s() when emulation has not started."; static const char* msg = "cannot call %s() when emulation has not started.";
switch(unstartedSeverity) switch(unstartedSeverity)
@ -1361,25 +1354,36 @@ DEFINE_LUA_FUNCTION(emulua_speedmode, "mode")
}*/ }*/
// I didn't make it clear enough what this function needs to do, so I'll spell it out this time:
// 1: This function needs to cause emulation to run for 1 full frame, until the next frame boundary
// (more importantly, the duration it runs for must correspond with 1 frame of input recording movies).
// 2: This function needs to return AFTER the frame of emulation has completely finished running.
// 3: This function needs to work when it is called from the SAME thread as the emulation (CPU thread).
// 4: This function needs to leave the emulation in a normal, UNPAUSED state.
DEFINE_LUA_FUNCTION(emulua_frameadvance, "") DEFINE_LUA_FUNCTION(emulua_frameadvance, "")
{ {
if(FailVerifyAtFrameBoundary(L, "emu.frameadvance", 0,1)) if(FailVerifyAtFrameBoundary(L, "emu.frameadvance", 0,1))
return emulua_wait(L); return emulua_wait(L);
if(Core::GetState() == Core::CORE_UNINITIALIZED || Core::GetState() == Core::CORE_STOPPING)
return emulua_wait(L);
int uid = luaStateToUIDMap[L];
LuaContextInfo& info = GetCurrentInfo(); LuaContextInfo& info = GetCurrentInfo();
info.ranFrameAdvance = true; info.ranFrameAdvance = true;
Frame::SetFrameStepping(true);
// Should step exactly one frame // set to stop the run loop after 1 frame
Core::SetState(Core::CORE_RUN); Frame::SetFrameStopping(true);
//while(Core::GetState() != Core::CORE_PAUSE && !info.panic); // run 1 frame
if(info.speedMode == SPEEDMODE_MAXIMUM)
CPluginManager::GetInstance().GetVideo()->Video_SetRendering(false);
if(Core::GetState() == Core::CORE_PAUSE)
Core::SetState(Core::CORE_RUN);
PowerPC::RunLoop();
// continue as normal
if(info.speedMode == SPEEDMODE_MAXIMUM)
CPluginManager::GetInstance().GetVideo()->Video_SetRendering(true);
Frame::SetFrameStopping(false);
*PowerPC::GetStatePtr() = PowerPC::CPU_RUNNING;
return 0; return 0;
} }
@ -1407,7 +1411,7 @@ DEFINE_LUA_FUNCTION(emulua_redraw, "")
DEFINE_LUA_FUNCTION(memory_readbyte, "address") DEFINE_LUA_FUNCTION(memory_readbyte, "address")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
unsigned char value = Memory::Read_U8(address); unsigned char value = Memory::Read_U8(address);
lua_settop(L,0); lua_settop(L,0);
lua_pushinteger(L, value); lua_pushinteger(L, value);
@ -1415,7 +1419,7 @@ DEFINE_LUA_FUNCTION(memory_readbyte, "address")
} }
DEFINE_LUA_FUNCTION(memory_readbytesigned, "address") DEFINE_LUA_FUNCTION(memory_readbytesigned, "address")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
signed char value = (signed char)(Memory::Read_U8(address)); signed char value = (signed char)(Memory::Read_U8(address));
lua_settop(L,0); lua_settop(L,0);
lua_pushinteger(L, value); lua_pushinteger(L, value);
@ -1423,7 +1427,7 @@ DEFINE_LUA_FUNCTION(memory_readbytesigned, "address")
} }
DEFINE_LUA_FUNCTION(memory_readword, "address") DEFINE_LUA_FUNCTION(memory_readword, "address")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
unsigned short value = Memory::Read_U16(address); unsigned short value = Memory::Read_U16(address);
lua_settop(L,0); lua_settop(L,0);
lua_pushinteger(L, value); lua_pushinteger(L, value);
@ -1431,7 +1435,7 @@ DEFINE_LUA_FUNCTION(memory_readword, "address")
} }
DEFINE_LUA_FUNCTION(memory_readwordsigned, "address") DEFINE_LUA_FUNCTION(memory_readwordsigned, "address")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
signed short value = (signed short)(Memory::Read_U16(address)); signed short value = (signed short)(Memory::Read_U16(address));
lua_settop(L,0); lua_settop(L,0);
lua_pushinteger(L, value); lua_pushinteger(L, value);
@ -1439,7 +1443,7 @@ DEFINE_LUA_FUNCTION(memory_readwordsigned, "address")
} }
DEFINE_LUA_FUNCTION(memory_readdword, "address") DEFINE_LUA_FUNCTION(memory_readdword, "address")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
unsigned long value = Memory::Read_U32(address); unsigned long value = Memory::Read_U32(address);
lua_settop(L,0); lua_settop(L,0);
lua_pushinteger(L, value); lua_pushinteger(L, value);
@ -1447,7 +1451,7 @@ DEFINE_LUA_FUNCTION(memory_readdword, "address")
} }
DEFINE_LUA_FUNCTION(memory_readdwordsigned, "address") DEFINE_LUA_FUNCTION(memory_readdwordsigned, "address")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
signed long value = (signed long)(Memory::Read_U32(address)); signed long value = (signed long)(Memory::Read_U32(address));
lua_settop(L,0); lua_settop(L,0);
lua_pushinteger(L, value); lua_pushinteger(L, value);
@ -1455,7 +1459,7 @@ DEFINE_LUA_FUNCTION(memory_readdwordsigned, "address")
} }
DEFINE_LUA_FUNCTION(memory_readqword, "address") DEFINE_LUA_FUNCTION(memory_readqword, "address")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
unsigned long long value = Memory::Read_U64(address); unsigned long long value = Memory::Read_U64(address);
lua_settop(L,0); lua_settop(L,0);
lua_pushinteger(L, (lua_Integer)value); lua_pushinteger(L, (lua_Integer)value);
@ -1463,7 +1467,7 @@ DEFINE_LUA_FUNCTION(memory_readqword, "address")
} }
DEFINE_LUA_FUNCTION(memory_readqwordsigned, "address") DEFINE_LUA_FUNCTION(memory_readqwordsigned, "address")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
signed long long value = (signed long long)(Memory::Read_U64(address)); signed long long value = (signed long long)(Memory::Read_U64(address));
lua_settop(L,0); lua_settop(L,0);
lua_pushinteger(L, (lua_Integer)value); lua_pushinteger(L, (lua_Integer)value);
@ -1472,28 +1476,28 @@ DEFINE_LUA_FUNCTION(memory_readqwordsigned, "address")
DEFINE_LUA_FUNCTION(memory_writebyte, "address,value") DEFINE_LUA_FUNCTION(memory_writebyte, "address,value")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
unsigned char value = (unsigned char)(luaL_checkinteger(L,2) & 0xFF); unsigned char value = (unsigned char)(luaL_checkinteger(L,2) & 0xFF);
Memory::Write_U8(value, address); Memory::Write_U8(value, address);
return 0; return 0;
} }
DEFINE_LUA_FUNCTION(memory_writeword, "address,value") DEFINE_LUA_FUNCTION(memory_writeword, "address,value")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
unsigned short value = (unsigned short)(luaL_checkinteger(L,2) & 0xFFFF); unsigned short value = (unsigned short)(luaL_checkinteger(L,2) & 0xFFFF);
Memory::Write_U16(value, address); Memory::Write_U16(value, address);
return 0; return 0;
} }
DEFINE_LUA_FUNCTION(memory_writedword, "address,value") DEFINE_LUA_FUNCTION(memory_writedword, "address,value")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
unsigned long value = (unsigned long)(luaL_checkinteger(L,2)); unsigned long value = (unsigned long)(luaL_checkinteger(L,2));
Memory::Write_U32(value, address); Memory::Write_U32(value, address);
return 0; return 0;
} }
DEFINE_LUA_FUNCTION(memory_writeqword, "address,value") DEFINE_LUA_FUNCTION(memory_writeqword, "address,value")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
unsigned long value = (unsigned long)(luaL_checkinteger(L,2)); unsigned long value = (unsigned long)(luaL_checkinteger(L,2));
Memory::Write_U64(value, address); Memory::Write_U64(value, address);
return 0; return 0;
@ -1501,7 +1505,7 @@ DEFINE_LUA_FUNCTION(memory_writeqword, "address,value")
DEFINE_LUA_FUNCTION(memory_readbyterange, "address,length") DEFINE_LUA_FUNCTION(memory_readbyterange, "address,length")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
int length = (int)luaL_checkinteger(L,2); int length = (int)luaL_checkinteger(L,2);
if(length < 0) if(length < 0)
@ -1530,7 +1534,7 @@ DEFINE_LUA_FUNCTION(memory_readbyterange, "address,length")
DEFINE_LUA_FUNCTION(memory_isvalid, "address") DEFINE_LUA_FUNCTION(memory_isvalid, "address")
{ {
unsigned long address = (unsigned long)luaL_checknumber(L,1); unsigned long address = luaL_checkinteger(L,1);
lua_settop(L,0); lua_settop(L,0);
lua_pushboolean(L, Memory::IsRAMAddress(address)); lua_pushboolean(L, Memory::IsRAMAddress(address));
return 1; return 1;
@ -2963,7 +2967,7 @@ DEFINE_LUA_FUNCTION(input_getcurrentinputstatus, "")
{ {
lua_newtable(L); lua_newtable(L);
// TODO: Use pad plugin's input // TODO: implement this (NOT using the pad plugin's input, because that's useless for this purpose)
/* /*
// keyboard and mouse button status // keyboard and mouse button status
{ {
@ -3632,6 +3636,8 @@ void RequestAbortLuaScript(int uid, const char* message)
info.L->hookcount = 1; // run hook function as soon as possible info.L->hookcount = 1; // run hook function as soon as possible
info.panic = true; // and call luaL_error once we're inside the hook function info.panic = true; // and call luaL_error once we're inside the hook function
info.restart = false; // also cancel prior restart requests
if(message) if(message)
{ {
strncpy(info.panicMessage, message, sizeof(info.panicMessage)); strncpy(info.panicMessage, message, sizeof(info.panicMessage));
@ -3793,9 +3799,6 @@ void StopLuaScript(int uid)
LuaContextInfo& info = *infoPtr; LuaContextInfo& info = *infoPtr;
if(info.ranFrameAdvance)
Frame::SetFrameStepping(false);
if(info.running) if(info.running)
{ {
// if it's currently running then we can't stop it now without crashing // if it's currently running then we can't stop it now without crashing

View File

@ -21,12 +21,14 @@
#include "PluginManager.h" #include "PluginManager.h"
#include "Thread.h" #include "Thread.h"
#include "FileUtil.h" #include "FileUtil.h"
#include "PowerPC/PowerPC.h"
Common::CriticalSection cs_frameSkip; Common::CriticalSection cs_frameSkip;
namespace Frame { namespace Frame {
bool g_bFrameStep = false; bool g_bFrameStep = false;
bool g_bFrameStop = false;
bool g_bAutoFire = false; bool g_bAutoFire = false;
u32 g_autoFirstKey = 0, g_autoSecondKey = 0; u32 g_autoFirstKey = 0, g_autoSecondKey = 0;
bool g_bFirstKey = true; bool g_bFirstKey = true;
@ -53,6 +55,11 @@ void FrameUpdate() {
if (g_bFrameStep) if (g_bFrameStep)
Core::SetState(Core::CORE_PAUSE); Core::SetState(Core::CORE_PAUSE);
// ("framestop") the only purpose of this is to cause interpreter/jit Run() to return temporarily.
// after that we set it back to CPU_RUNNING and continue as normal.
if (g_bFrameStop)
*PowerPC::GetStatePtr() = PowerPC::CPU_STEPPING;
if(g_framesToSkip) if(g_framesToSkip)
FrameSkipping(); FrameSkipping();
@ -123,6 +130,9 @@ bool IsAutoFiring() {
void SetFrameStepping(bool bEnabled) { void SetFrameStepping(bool bEnabled) {
g_bFrameStep = bEnabled; g_bFrameStep = bEnabled;
} }
void SetFrameStopping(bool bEnabled) {
g_bFrameStop = bEnabled;
}
void ModifyController(SPADStatus *PadStatus, int controllerID) void ModifyController(SPADStatus *PadStatus, int controllerID)
{ {

View File

@ -100,6 +100,7 @@ void SetAutoHold(bool bEnabled, u32 keyToHold = 0);
void SetAutoFire(bool bEnabled, u32 keyOne = 0, u32 keyTwo = 0); void SetAutoFire(bool bEnabled, u32 keyOne = 0, u32 keyTwo = 0);
void SetFrameStepping(bool bEnabled); void SetFrameStepping(bool bEnabled);
void SetFrameStopping(bool bEnabled);
void SetFrameSkipping(unsigned int framesToSkip); void SetFrameSkipping(unsigned int framesToSkip);
int FrameSkippingFactor(); int FrameSkippingFactor();

View File

@ -51,8 +51,8 @@ void LuaStop(int uid, bool ok)
{ {
if(ok) if(ok)
g_contextMap[uid]->PrintMessage("Script completed successfully!\n"); g_contextMap[uid]->PrintMessage("Script completed successfully!\n");
else //else // disabled because this message makes no sense in certain contexts, and there's always an earlier error message anyway.
g_contextMap[uid]->PrintMessage("Script failed\n"); // g_contextMap[uid]->PrintMessage("Script failed.\n");
g_contextMap[uid]->OnStop(); g_contextMap[uid]->OnStop();
} }
@ -173,7 +173,7 @@ void wxLuaWindow::OnEvent_ScriptStop_Press(wxCommandEvent& WXUNUSED(event))
{ {
CoreTiming::ScheduleEvent_Threadsafe_Immediate(ev_LuaStop, luaID); CoreTiming::ScheduleEvent_Threadsafe_Immediate(ev_LuaStop, luaID);
OnStop(); OnStop();
PrintMessage("Script stopped!\n"); PrintMessage("Stopping script...\n");
} }
void wxLuaWindow::OnStop() void wxLuaWindow::OnStop()