Skip to content

Commit

Permalink
fixed setTimeout, setInterval, clearInterval
Browse files Browse the repository at this point in the history
example usage:
setTimeout(function () {
  print("setTimeout");
}, 1000);

var t = setInterval(function () {
  print("setInterval");
}, 1000);

delay(5000);

clearInterval(t);
  • Loading branch information
noah- committed Aug 22, 2018
1 parent 8ffc6b5 commit 045c847
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 89 deletions.
1 change: 1 addition & 0 deletions D2BS.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define XP_WIN

#define D2BS_VERSION "1.5.1869"
#define D2BS_VERSION "1.5.1870"

#include <windows.h>
#include <vector>
Expand Down
68 changes: 33 additions & 35 deletions JSCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,61 +56,59 @@ JSAPI_FUNC(my_print)
}
return JS_TRUE;
}

JSAPI_FUNC(my_setTimeout)
{
JS_SET_RVAL(cx, vp, JSVAL_NULL);
Script* script = (Script*)JS_GetContextPrivate(cx);

if (argc < 2 || !JSVAL_IS_NUMBER(JS_ARGV(cx, vp)[1]))
JS_ReportError(cx, "invalid prams passed to setTimeout");

int freq = JSVAL_TO_INT( JS_ARGV(cx, vp)[1]);
Event* evt = new Event;
evt->owner = script;
evt->argc = argc;
evt->name ="setTimeout";
evt->argv = new JSAutoStructuredCloneBuffer*;
for(uintN i = 0; i < argc; i++)
{
evt->argv[i] = new JSAutoStructuredCloneBuffer;
evt->argv[i]->write(cx, JS_ARGV(cx, vp)[i]);
}

JS_SET_RVAL(cx, vp, INT_TO_JSVAL(ScriptEngine::AddDelayedEvent(evt, freq)));
JS_ReportError(cx, "invalid params passed to setTimeout");

return JS_FALSE;
if(JSVAL_IS_FUNCTION(cx, JS_ARGV(cx, vp)[0]) && JSVAL_IS_NUMBER(JS_ARGV(cx, vp)[1]))
{
Script* self = (Script*)JS_GetContextPrivate(cx);
int freq = JSVAL_TO_INT( JS_ARGV(cx, vp)[1]);
self->RegisterEvent("setTimeout", JS_ARGV(cx, vp)[0]);
Event* evt = new Event;
evt->owner = self;
evt->name = "setTimeout";
evt->arg3 = new jsval(JS_ARGV(cx, vp)[0]);
JS_SET_RVAL(cx, vp, INT_TO_JSVAL(ScriptEngine::AddDelayedEvent(evt, freq)));
}

return JS_TRUE;
}

JSAPI_FUNC(my_setInterval)
{
JS_SET_RVAL(cx, vp, JSVAL_NULL);
Script* script = (Script*)JS_GetContextPrivate(cx);

if (argc < 2 || !JSVAL_IS_NUMBER(JS_ARGV(cx, vp)[1]))
JS_ReportError(cx, "invalid prams passed to setTimeout");

int freq = JSVAL_TO_INT( JS_ARGV(cx, vp)[1]);
Event* evt = new Event;
evt->owner = script;
evt->argc = argc;
evt->name ="setInterval";
evt->argv = new JSAutoStructuredCloneBuffer*;
for(uintN i = 0; i < argc; i++)
{
evt->argv[i] = new JSAutoStructuredCloneBuffer;
evt->argv[i]->write(cx, JS_ARGV(cx, vp)[i]);
}

JS_SET_RVAL(cx, vp, INT_TO_JSVAL(ScriptEngine::AddDelayedEvent(evt, freq)));
JS_ReportError(cx, "invalid params passed to setInterval");

return JS_FALSE;
if(JSVAL_IS_FUNCTION(cx, JS_ARGV(cx, vp)[0]) && JSVAL_IS_NUMBER(JS_ARGV(cx, vp)[1]))
{
Script* self = (Script*)JS_GetContextPrivate(cx);
int freq = JSVAL_TO_INT( JS_ARGV(cx, vp)[1]);
self->RegisterEvent("setInterval", JS_ARGV(cx, vp)[0]);
Event* evt = new Event;
evt->owner = self;
evt->name = "setInterval";
evt->arg3 = new jsval(JS_ARGV(cx, vp)[0]);
JS_SET_RVAL(cx, vp, INT_TO_JSVAL(ScriptEngine::AddDelayedEvent(evt, freq)));
}

return JS_TRUE;

}
JSAPI_FUNC(my_clearInterval)
{
JS_SET_RVAL(cx, vp, JSVAL_NULL);
if (argc != 1 || !JSVAL_IS_NUMBER(JS_ARGV(cx, vp)[0]))
JS_ReportError(cx, "invalid prams passed to setTimeout");
JS_ReportError(cx, "params prams passed to clearInterval");

ScriptEngine::RemoveDelayedEvent(JSVAL_TO_INT(JS_ARGV(cx, vp)[0]));
JS_free(cx, "setInterval");
return JS_TRUE;
}
JSAPI_FUNC(my_delay)
Expand Down
67 changes: 13 additions & 54 deletions ScriptEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -845,51 +845,20 @@ bool ExecScriptEvent(Event* evt, bool clearList)
if (strcmp(evtName, "setTimeout") == 0 || strcmp(evtName, "setInterval") == 0) {
if(!clearList)
{
JS_BeginRequest(cx);
jsval* argv = new jsval[evt->argc];
for(uintN i = 0; i < evt->argc; i++)
evt->argv[i]->read(cx, &argv[i]);

for(int j = 0 ; j < evt->argc; j++)
JS_AddValueRoot(cx, &argv[j]);
if(JSVAL_IS_STRING(argv[0]))
{
std::string test ;
test.append( "try{ ");
test.append( JS_EncodeString(cx,JS_ValueToString(cx, argv[0])) );
test.append(" } catch (error){print(error)}");
jsval rval;
if(JS_EvaluateScript(cx, JS_GetGlobalObject(cx), test.data() , test.length(), "setTimeout", 0, &rval))
{
if(!JSVAL_IS_NULL(rval) && !JSVAL_IS_VOID(rval))
{
JS_ConvertValue(cx, rval, JSTYPE_STRING, &rval);
char* text = JS_EncodeString(cx,JS_ValueToString(cx, rval));
std::replace(text, text + strlen(text), '%', (char)(unsigned char)0xFE);
Print(text);
JS_free(cx, text);
}
}
}

if(JSVAL_IS_FUNCTION(cx,argv[0])) //not working
{

jsval rval;
JS_CallFunctionValue(cx, JS_GetGlobalObject(cx), argv[0], evt->argc-2, &argv[2], &rval);


}
JS_BeginRequest(cx);
jsval rval;
for(FunctionList::iterator it = evt->owner->functions[evtName].begin(); it != evt->owner->functions[evtName].end(); it++)
{
JS_CallFunctionValue(cx, JS_GetGlobalObject(cx), *(*it)->value(), 0, &rval, &rval);
}
JS_EndRequest(cx);
for(int j = 0 ; j < evt->argc; j++)
JS_RemoveValueRoot(cx, &argv[j]);
}

}

if (strcmp(evtName, "setTimeout") == 0)
{
ScriptEngine::RemoveDelayedEvent(*(DWORD*) evt->arg1);
}
JS_free(cx, "setTimeout");
}

return true;
}
Expand All @@ -903,7 +872,7 @@ bool ExecScriptEvent(Event* evt, bool clearList)
int ScriptEngine::AddDelayedEvent(Event* evt, int freq)
{
delayedExecKey++;
evt->arg1 = new DWORD(delayedExecKey);
evt->arg1 = new DWORD(delayedExecKey);
evt->arg2 = CreateWaitableTimer(NULL,true,NULL);

__int64 start;
Expand All @@ -928,23 +897,13 @@ int ScriptEngine::AddDelayedEvent(Event* evt, int freq)
it = DelayedExecList.begin();
while(it != DelayedExecList.end())
{
if( *(DWORD*)(*it)->arg1 == key)
if(*(DWORD*)(*it)->arg1 == key)
{
//remove from script list if its already poped but not executed.
list<Event*>::iterator sit;
sit=(*it)->owner->EventList.begin();
if( *(DWORD*)(*sit)->arg1 == key)
sit = (*it)->owner->EventList.erase(sit);
else
sit++;

CancelWaitableTimer((HANDLE*)(*it)->arg2);
CloseHandle((HANDLE*)(*it)->arg2);
Event* evt = *it;
for(uintN i = 0; i < evt->argc; i++){
evt->argv[i]->clear();
delete evt->argv[i];
}
evt->owner->UnregisterEvent(evt->name, *(jsval*) evt->arg3);
delete evt->arg3;
delete evt;
it = DelayedExecList.erase(it);
}
Expand Down

0 comments on commit 045c847

Please sign in to comment.