diff --git a/src/context.cpp b/src/context.cpp index 72d3bf13..99391c80 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -54,17 +54,33 @@ void fsigpipe (int Sig); int got_sigpipe; +bool Context::factory_initialized = false; + +static void init_factory() { + Factory::set_default_classtype("GeometryLayer", "basic"); + Factory::set_default_classtype("KeyboardController", "sdl"); + Factory::set_default_classtype("TriggerController", "core"); + Factory::set_default_classtype("Screen", "sdl"); + Factory::set_default_classtype("MovieLayer", "ffmpeg"); + Factory::set_default_classtype("GeneratorLayer","ff_f0r"); + Factory::set_default_classtype("ImageLayer","sdl"); +#ifdef WITH_UNICAP + Factory::set_default_classtype("CamLayer", "unicap"); +#endif +#ifdef WITH_OPENCV + Factory::set_default_classtype("CamLayer", "opencv"); +#endif +#ifdef WITH_CAIRO + Factory::set_default_classtype("VectorLayer", "cairo"); +#endif +#ifdef WITH_TEXTLAYER + Factory::set_default_classtype("TextLayer", "truetype"); +#endif +} + void * run_context(void * data){ Context * context = (Context *)data; context->start(); - /* - context->quit = false; - while(!context->quit) { - context->cafudda(0.0); - pthread_yield(); - SDL_framerateDelay(&FPS); // synced with desired fps here - } - */ pthread_exit(NULL); } @@ -122,26 +138,9 @@ Context::Context() { #endif "\n"; - - Factory::set_default_classtype("GeometryLayer", "basic"); - Factory::set_default_classtype("KeyboardController", "sdl"); - Factory::set_default_classtype("TriggerController", "core"); - Factory::set_default_classtype("Screen", "sdl"); - Factory::set_default_classtype("MovieLayer", "ffmpeg"); - Factory::set_default_classtype("GeneratorLayer","ff_f0r"); - Factory::set_default_classtype("ImageLayer","sdl"); -#ifdef WITH_UNICAP - Factory::set_default_classtype("CamLayer", "unicap"); -#endif -#ifdef WITH_OPENCV - Factory::set_default_classtype("CamLayer", "opencv"); -#endif -#ifdef WITH_CAIRO - Factory::set_default_classtype("VectorLayer", "cairo"); -#endif -#ifdef WITH_TEXTLAYER - Factory::set_default_classtype("TextLayer", "truetype"); -#endif + if (!factory_initialized) + init_factory(); + assert( init() ); } diff --git a/src/context_js.cpp b/src/context_js.cpp index a29fb342..05cdd71e 100644 --- a/src/context_js.cpp +++ b/src/context_js.cpp @@ -736,6 +736,7 @@ JS(execute_javascript_command) { return JS_TRUE; } +// XXX - are we sure that we really want to expose such a function? :/ JS(system_exec) { func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__); diff --git a/src/controller.cpp b/src/controller.cpp index 4888cf95..f8d85e2d 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -36,6 +36,11 @@ Controller::Controller() { Controller::~Controller() { func("%s %s (%p)",__PRETTY_FUNCTION__, name, this); + ControllerListener *listener = listeners.begin(); + while (listener) { + delete listener; + listener = listeners.begin(); + } } bool Controller::init(Context *freej) { @@ -43,14 +48,11 @@ bool Controller::init(Context *freej) { env = freej; if(freej->js) { - jsenv = JS_NewContext(freej->js->js_runtime, STACK_CHUNK_SIZE);//freej->js->global_context; - // the object is set to global, but should be overwritten // in every specific object constructor with the "obj" from JS // XXX - set initial value to NULL instead of creating a fake useless object - jsobj = JS_NewObject(jsenv, &global_class, NULL, freej->js->global_object); - //init_class(jsenv, obj); - + jsenv = freej->js->global_context; + jsobj = freej->js->global_object; } initialized = true; @@ -91,7 +93,7 @@ bool Controller::add_listener(JSContext *cx, JSObject *obj) void Controller::reset() { - JSBool res; + active = false; ControllerListener *listener = listeners.begin(); while (listener) { delete listener; @@ -101,7 +103,6 @@ void Controller::reset() int Controller::JSCall(const char *funcname, int argc, jsval *argv) { - JSBool res; ControllerListener *listener = listeners.begin(); while (listener) { // TODO - unregister listener if returns false diff --git a/src/include/context.h b/src/include/context.h index 73db8adf..ef9c5101 100644 --- a/src/include/context.h +++ b/src/include/context.h @@ -65,7 +65,7 @@ template class Linklist; class Context { private: - + static bool factory_initialized; /* doublesize calculation */ uint64_t **doubletab; Uint8 *doublebuf; diff --git a/src/include/jsparser.h b/src/include/jsparser.h index eedf0f6b..d2c2e12a 100644 --- a/src/include/jsparser.h +++ b/src/include/jsparser.h @@ -34,18 +34,32 @@ * malloc overhead/fragmentation for deep or highly-variable stacks. */ #define STACK_CHUNK_SIZE 8192 -//#include -//#include +#include #include // spidermonkey header extern Context *global_environment; void js_debug_property(JSContext *cx, jsval val); void js_debug_argument(JSContext *cx, jsval val); -class JsExecutionContext; + +// This class represents the execution context for a single script, +// holding its context, runtime and global object. +class JsExecutionContext : public Entry { + friend class JsParser; +public: + JsExecutionContext(JsParser *jsParser); + ~JsExecutionContext(); +private: + void init_class(); + + + JsParser *parser; + JSContext *cx; + JSRuntime *rt; + JSObject *obj; // the global object +}; class JsParser { - friend class JsExecutionContext; public: JsParser(Context *_env); ~JsParser(); @@ -61,17 +75,19 @@ class JsParser { JSBool branch_callback(JSContext* Context, JSScript* Script); + /* DEPRECATED!! here for retrocompatibility */ JSContext *global_context; JSObject *global_object; - JsExecutionContext *global_runtime; - JSRuntime *js_runtime; - + /** **/ + + JsExecutionContext *global_runtime; + Linklist runtimes; + private: void init(); void init_class(JSContext *cx, JSObject *obj); int open(JSContext *cx, JSObject *obj, const char* script_file); - JSScript *running_scripts; }; #endif diff --git a/src/jsparser.cpp b/src/jsparser.cpp index 4480cf64..80a714e5 100644 --- a/src/jsparser.cpp +++ b/src/jsparser.cpp @@ -45,22 +45,6 @@ Context *global_environment; -/* TODO - move in a specific file */ -class JsExecutionContext : public Entry { - friend class JsParser; - public: - JsExecutionContext(JsParser *jsParser); - ~JsExecutionContext(); - private: - void init_class(); - - - JsParser *parser; - JSContext *cx; - JSRuntime *rt; - JSObject *obj; // the global object -}; - JsExecutionContext::JsExecutionContext(JsParser *jsParser) { parser = jsParser; @@ -107,6 +91,17 @@ JsExecutionContext::JsExecutionContext(JsParser *jsParser) } +JsExecutionContext::~JsExecutionContext() +{ + JS_SetContextThread(cx); + JS_BeginRequest(cx); + JS_ClearScope(cx, obj); + JS_EndRequest(cx); + //JS_ClearContextThread(cx); + JS_DestroyContext(cx); + JS_DestroyRuntime(rt); +} + void JsExecutionContext::init_class() { /* Initialize the built-in JS objects and the global object @@ -360,12 +355,6 @@ void JsExecutionContext::init_class() { return; } -JsExecutionContext::~JsExecutionContext() -{ - JS_DestroyContext(cx); - JS_DestroyRuntime(rt); -} - JsParser::JsParser(Context *_env) { if(_env!=NULL) global_environment=_env; @@ -470,6 +459,11 @@ int JsParser::open(const char* script_file) { int ret = open(new_script->cx, new_script->obj, script_file); JS_EndRequest(new_script->cx); JS_ClearContextThread(new_script->cx); + if (ret) + runtimes.append(new_script); + else + delete new_script; + return ret; } @@ -686,24 +680,13 @@ int JsParser::reset() { JSContext *iterp = NULL; int i = 0; - while ((cx = JS_ContextIterator(js_runtime, &iterp)) != NULL) { - if (cx == global_context) // skip the global context - continue; - - JS_SetContextThread(cx); - JS_BeginRequest(cx); - JSObject *obj = JS_GetGlobalObject(cx); - if (obj) - JS_ClearScope(cx, obj); - JS_EndRequest(cx); - JS_ClearContextThread(cx); - + JsExecutionContext *ecx = runtimes.begin(); + while (ecx) { + delete ecx; + ecx = runtimes.begin(); + i++; } - JS_BeginRequest(global_context); - JS_ClearScope(global_context, global_object); - //init_class(global_context, global_object); - JS_EndRequest(global_context); - return 0; + return i; } void js_debug_property(JSContext *cx, jsval vp) { diff --git a/xcode/CKbdController.mm b/xcode/CKbdController.mm index d2f8bb91..90d18228 100644 --- a/xcode/CKbdController.mm +++ b/xcode/CKbdController.mm @@ -25,6 +25,7 @@ CKbdController::CKbdController() : Controller() { windowController = NULL; + indestructible = true; // we are going to be used as a singleton } CKbdController::~CKbdController() diff --git a/xcode/config.h b/xcode/config.h index cd3bd116..1645d139 100644 --- a/xcode/config.h +++ b/xcode/config.h @@ -254,6 +254,6 @@ #define ICECASTPORT "8000" -#define JS_THREADSAFE +#define JS_THREADSAFE 1 #endif