//-------------- dzzie
typedef int(__stdcall* vbCallback)(int, char*);
int opCounter = 0;
int g_AbortScript = 0;
vbCallback vbTimeOutHandler = 0;
void __declspec(dllexport) __stdcall SetTimeoutCallBack(void* lpfnTimeoutHandler) {vbTimeOutHandler = (vbCallback)lpfnTimeoutHandler;}
void __declspec(dllexport) __stdcall SetGlobalAbort(int gAbort) { g_AbortScript = gAbort; }
int dz_timeoutHandler(void) {
int timedOut = 0;
if (g_AbortScript == 1) return 1; //is it better to still receive the heartbeat for ui refresh? should be ending very soon...
if (vbTimeOutHandler != NULL && opCounter != 0 && (opCounter % 1000) == 0) {
opCounter = 0;
timedOut = vbTimeOutHandler(0, 0);
if (timedOut == 1) g_AbortScript = 1;
}
opCounter++;
return timedOut;
}
//--------------- dzzie
/* Do interpreter dispatch accounting for tracing and instrumentation */
#define DISPATCH()
{
NEXTOPARG();
PRE_DISPATCH_GOTO();
assert(cframe.use_tracing == 0 || cframe.use_tracing == 255);
opcode |= cframe.use_tracing OR_DTRACE_LINE;
if(dz_timeoutHandler()==1) goto exit_unwind;
DISPATCH_GOTO();
}
...
start_frame:
if(g_AbortScript == 1) goto exit_unwind; //dzzie
...
resume_frame:
if (g_AbortScript == 1) goto exit_unwind; //dzzie
Public Function cb_TimeoutHandler(ByVal t As Long, ByVal lpMsg As Long) As Long
'return 1 to halt execution, 0 to continue
DoEvents 'allow our timer and UI to breath in case its a dead loop
If ABORT_SCRIPT Then
cb_TimeoutHandler = 1
Debug.Print "Aborting!"
Else
cb_TimeoutHandler = 0
End If
End Function
Function UseTimeoutHandler() As Boolean
Dim h As Long, p As Long
h = LoadLibrary("python311.dll")
If h = 0 Then Exit Function
p = GetProcAddress(h, "_SetTimeoutCallBack@4")
If p = 0 Then Exit Function
SetTimeoutCallBack AddressOf cb_TimeoutHandler
UseTimeoutHandler = True
End Function