Exemplo n.º 1
0
static int js_module_read_file(duk_context* ctx)
{
    JSVM* vm = JSVM::GetJSVM(ctx);

    ResourceCache* cache = vm->GetContext()->GetSubsystem<ResourceCache>();

    String path = duk_to_string(ctx, 0);

    SharedPtr<File> file = cache->GetFile(path);

    if (!file->IsOpen())
    {
        duk_push_string(ctx, "Unable to open module file");
        duk_throw(ctx);
        return 0;
    }

    unsigned size = file->GetSize();

    SharedArrayPtr<char> data;
    data = new char[size + 1];
    data[size] = '\0';
    file->Read(data, size);

    duk_push_string(ctx, data);

    return 1;
}
Exemplo n.º 2
0
    void ClockworkPlayerApp::Start()
    {
        Application::Start();

        // Instantiate and register NETCore subsystem
        context_->RegisterSubsystem(new NETCore(context_));

        // Instantiate and register the Javascript subsystem
        Javascript* javascript = new Javascript(context_);
        context_->RegisterSubsystem(javascript);

        vm_ = javascript->InstantiateVM("MainVM");
        vm_->InitJSContext();

        UI* ui = GetSubsystem<UI>();
        ui->Initialize("DefaultUI/language/lng_en.tb.txt");
        ui->LoadDefaultPlayerSkin();

        vm_->SetModuleSearchPaths("Modules");

        // Instantiate and register the Player subsystem
        context_->RegisterSubsystem(new ClockworkPlayer::Player(context_));
        ClockworkPlayer::jsapi_init_clockworkplayer(vm_);

        JSVM* vm = JSVM::GetJSVM(0);

        if (!vm->ExecuteMain())
        {
            SendEvent(E_EXITREQUESTED);
        }


        return;
    }
Exemplo n.º 3
0
static int UIButton_Popup(duk_context* ctx)
{

    if (!duk_is_object(ctx, 0))
    {
        duk_push_string(ctx, "UIButton.popup first argument must be an object");
        duk_throw(ctx);
    }
    if (!duk_is_callable(ctx, 1))
    {
        duk_push_string(ctx, "UIButton.popup second argument must be callable");
        duk_throw(ctx);
    }

    JSVM* vm = JSVM::GetJSVM(ctx);

    duk_enum(ctx, 0, DUK_ENUM_OWN_PROPERTIES_ONLY);

    UISelectItemSource* source = new UISelectItemSource(vm->GetContext());

    while (duk_next(ctx, -1, 0)) {

        String key = duk_get_string(ctx, -1);

        duk_get_prop(ctx, 0);

        if (duk_is_array(ctx, -1))
        {
            // need to support this, for skin image, etc
            assert(0);
        }
        else if (duk_is_string(ctx, -1))
        {
            // id
            String id = duk_get_string(ctx, -1);            
            source->AddItem(new UISelectItem(vm->GetContext(), key, id));
        }
        else
        {
            duk_push_string(ctx, "UIButton.popup data object key is not an array or string");
            duk_throw(ctx);
        }

        duk_pop(ctx);  // pop key value
    }

    duk_pop(ctx);  // pop enum object

    duk_push_this(ctx);

    duk_dup(ctx, 1);
    duk_put_prop_string(ctx, -2, "__popup_menu_callback");

    UIButton* button = js_to_class_instance<UIButton>(ctx, -1, 0);
    UIMenuWindow* menuWindow = new UIMenuWindow(vm->GetContext(), button, "__popup-menu");
    menuWindow->Show(source);
    duk_pop(ctx);

    return 0;
}
void JSEventDispatcher::EndSendEvent(Context* context, Object* sender, StringHash eventType, VariantMap& eventData)
{
    if (!jsEvents_.Contains(eventType))
        return;

    JSVM* vm = JSVM::GetJSVM(NULL);

    if (!vm)
        return;

    duk_context* ctx = vm->GetJSContext();

    duk_push_global_stash(ctx);
    duk_get_prop_index(ctx, -1, JS_GLOBALSTASH_VARIANTMAP_CACHE);

    duk_push_pointer(ctx, (void*) &eventData);
    duk_get_prop(ctx, -2);


    // If this issue is addressed, revisit this to simply remove
    // the variantmap object from the cache, if the user explicitly
    // keeps the event object alive in a local closure, that is allowed
    // (though, will keep object properties from being GC'd)
    // https://github.com/svaarala/duktape/issues/229

    // Ok, this is unfortunate, in an event callback it is possible
    // to capture the Proxy object which represents the event VariantMap
    // in a function() {} closure, which will keep the event data alive
    // until the function happens to be gc'd (it is a member of the eventhandler)
    // which will leave things like scenes up if there was a P_SCENE event data
    // member, etc
    // So, we need to check if we have an object in the variant map cache
    // and thense call it's delete property method on the Proxy, which will clear
    // all the data (the proxy can still be alive as a captured local, though
    // the members won't be held
    // This all makes it that much more important that the pointer to eventData
    // is consistent across entire event, otherwise references may be held

    // see note above about: https://github.com/svaarala/duktape/issues/229

    if (duk_is_object(ctx, -1))
    {
        // deletes all properties, thus freeing references, even if
        // the variant map object is held onto by script (it will be invalid, post
        // event send)
        // see JSAPI.cpp variantmap_property_deleteproperty
        duk_del_prop_index(ctx, -1, 0);

        duk_push_pointer(ctx, (void*) &eventData);
        duk_push_undefined(ctx);

        // clear the variant map object from the cache
        duk_put_prop(ctx, -4);

    }

    duk_pop_3(ctx);

}
Exemplo n.º 5
0
static int js_print(duk_context* ctx)
{
    duk_concat(ctx, duk_get_top(ctx));

    VariantMap eventData;
    using namespace JSPrint;
    eventData[P_TEXT] =  duk_to_string(ctx, -1);

    JSVM* vm = JSVM::GetJSVM(ctx);
    vm->SendEvent(E_JSPRINT, eventData);

    LOGINFOF("%s", duk_to_string(ctx, -1));
    return 0;
}
Exemplo n.º 6
0
void AEPlayerApplication::Start()
{
    AEEditorCommon::Start();

    UI* ui = GetSubsystem<UI>();
    ui->Initialize("DefaultUI/language/lng_en.tb.txt");
    ui->LoadDefaultPlayerSkin();

    context_->RegisterSubsystem(new PlayerMode(context_));
    PlayerMode* playerMode = GetSubsystem<PlayerMode>();
    playerMode->ProcessArguments();

    SubscribeToEvent(E_JSERROR, HANDLER(AEPlayerApplication, HandleJSError));

#ifdef ATOMIC_DOTNET
        if (debugPlayer_)
        {
           GetSubsystem<NETCore>()->WaitForDebuggerConnect();
        }
#endif

    vm_->SetModuleSearchPaths("Modules");

    // Instantiate and register the Player subsystem
    context_->RegisterSubsystem(new AtomicPlayer::Player(context_));
    AtomicPlayer::jsapi_init_atomicplayer(vm_);

#ifdef ATOMIC_DOTNET
    // Initialize Scripting Subsystem
    NETScript* netScript = new NETScript(context_);
    context_->RegisterSubsystem(netScript);
    netScript->Initialize();
    netScript->ExecMainAssembly();
#endif

    if (!playerMode->launchedByEditor())
    {
        JSVM* vm = JSVM::GetJSVM(0);

        if (!vm->ExecuteMain())
        {
            SendEvent(E_EXITREQUESTED);
        }
    }

    SubscribeToEvent(E_PLAYERQUIT, HANDLER(AEPlayerApplication, HandleQuit));

    return;
}
Exemplo n.º 7
0
    void IPCPlayerApp::Start()
    {

        if (subprocess_)
        {
            // do not execute main in the player app
            executeJSMain_ = false;
        }

        PlayerApp::Start();

        int id = -1;

        if (IPC::ProcessArguments(arguments_, id, fd_[0], fd_[1]))
        {
            SubscribeToEvent(E_IPCINITIALIZE, ATOMIC_HANDLER(IPCPlayerApp, HandleIPCInitialize));
            SubscribeToEvent(E_LOGMESSAGE, ATOMIC_HANDLER(IPCPlayerApp, HandleLogMessage));
            SubscribeToEvent(E_JSERROR, ATOMIC_HANDLER(IPCPlayerApp, HandleJSError));
            SubscribeToEvent(E_EXITREQUESTED, ATOMIC_HANDLER(IPCPlayerApp, HandleExitRequest));
            SubscribeToEvent(E_SCREENMODE, ATOMIC_HANDLER(IPCPlayerApp, HandlePlayerWindowChanged));
            SubscribeToEvent(E_WINDOWPOS, ATOMIC_HANDLER(IPCPlayerApp, HandlePlayerWindowChanged));
            SubscribeToEvent(E_UPDATESPAUSEDRESUMED, ATOMIC_HANDLER(IPCPlayerApp, HandleUpdatesPausedResumed));

            if (ipc_->InitWorker((unsigned)id, fd_[0], fd_[1]))
            {
                brokerActive_ = true;
            }
            else if (subprocess_)
            {
                ATOMIC_LOGERROR("IPCPlayerApp::Start() - Unable to initialize IPC Worker");
            }
        }

        if (subprocess_)
        {
            JSVM* vm = JSVM::GetJSVM(0);

            if (!vm->ExecuteMain())
            {
                SendEvent(E_EXITREQUESTED);
            }

            SubscribeToEvent(E_PLAYERQUIT, ATOMIC_HANDLER(IPCPlayerApp, HandleQuit));
        }

        GetSubsystem<Graphics>()->RaiseWindow();


    }
Exemplo n.º 8
0
static int js_atomic_script(duk_context* ctx)
{
    JSVM* vm = JSVM::GetJSVM(ctx);

    if (duk_is_string(ctx, 0))
    {
        if ( vm->ExecuteScript(duk_to_string(ctx, 0)))
            duk_push_boolean(ctx, 1);
        else
            duk_push_boolean(ctx, 0);
    }
    else
        duk_push_boolean(ctx, 0);

    return 1;
}
Exemplo n.º 9
0
void PlayerMode::HandleIPCInitialize(StringHash eventType, VariantMap& eventData)
{
    brokerActive_ = true;

    JSVM* vm = JSVM::GetJSVM(0);

    if (!vm->ExecuteMain())
    {
        SendEvent(E_EXITREQUESTED);
    }

    // BEGIN LICENSE MANAGEMENT

    licenseModule3D_ = eventData["license3D"].GetBool();

    // END LICENSE MANAGEMENT

    SystemUI::DebugHud* debugHud = GetSubsystem<SystemUI::DebugHud>();
    if (debugHud)
        debugHud->SetMode(eventData["debugHudMode"].GetUInt());

}
Exemplo n.º 10
0
    // see http://duktape.org/guide.html#modules   
    static int js_module_search(duk_context* ctx)
    {       
        JSVM* vm = JSVM::GetJSVM(ctx);
        FileSystem* fs = vm->GetSubsystem<FileSystem>();
        ResourceCache* cache = vm->GetSubsystem<ResourceCache>();

        int top = duk_get_top(ctx);

        assert(top ==  4);

        String moduleID = duk_to_string(ctx, 0);

        if (top > 1)
        {
            // require function
            assert(duk_is_function(ctx, 1));
        }
        
        if (top > 2)
        {
            // exports
            assert(duk_is_object(ctx, 2));
        }

        if (top > 3)        
        {
            // module (module.id == a resolved absolute identifier for the module being loaded)
            assert(duk_is_object(ctx, 3));
        }

        String pathName, fileName, extension;
        SplitPath(moduleID, pathName, fileName, extension);
        String path = moduleID;

        // Do we really want this?  It is nice to not have to specify the Atomic path
        if (fileName.StartsWith("Atomic"))
        {
            path = "AtomicModules/" + path + ".js";
        }
        else
        {
            path += ".js";

            if (!cache->Exists(path))
            {
                const Vector<String>& searchPaths = vm->GetModuleSearchPaths();
                for (unsigned i = 0; i < searchPaths.Size(); i++)
                {
                    String search = searchPaths[i] + path;
                    if (cache->Exists(search))
                    {
                        path = search;
                        break;
                    }
                }
            }
        }

        if (cache->Exists(path))
        {
            SharedPtr<File> jsfile(cache->GetFile(path, false));
            vm->SetLastModuleSearchFile(jsfile->GetFullPath());
            String source;
            jsfile->ReadText(source);
            source.Append('\n');
            duk_push_string(ctx, source.CString());
            return 1;
        }
        else
        {
            // we're not a JS file, so check if we're a native module
            const Vector<String>& resourceDirs = cache->GetResourceDirs();

            for (unsigned i = 0; i < resourceDirs.Size(); i++)
            {

             String pluginLibrary;

             // TODO: proper platform folder detection
#ifdef ATOMIC_PLATFORM_WINDOWS              
              pluginLibrary = resourceDirs.At(i) + "Plugins/Windows/x64/" + moduleID + ".dll";
#elif ATOMIC_PLATFORM_OSX
             pluginLibrary = resourceDirs.At(i) + "Plugins/Mac/x64/lib" + moduleID + ".dylib";
#endif

               if (pluginLibrary.Length() && fs->FileExists(pluginLibrary))
                {
                    // let duktape know we loaded a native module
                    if (jsplugin_load(vm, pluginLibrary))
                    {
                        duk_push_undefined(ctx);
                        return 1;
                    }
                    else
                    {
                        duk_push_sprintf(ctx, "Failed loading native plugins: %s", pluginLibrary.CString());
                        duk_throw(ctx);
                    }
                }
            }

        }

        duk_push_sprintf(ctx, "Failed loading module: %s", path.CString());
        duk_throw(ctx);

    }
void JSEventHelper::HandleEvent(StringHash eventType, VariantMap& eventData)
{
    if (object_.Null())
        return;

    JSVM* vm = JSVM::GetJSVM(0);
    duk_context* ctx = vm->GetJSContext();

    duk_idx_t top = duk_get_top(ctx);

    js_push_class_object_instance(ctx, this);

    duk_get_prop_string(ctx, -1, "__eventHelperFunctions");

    assert(duk_is_object(ctx, -1));

    duk_get_prop_string(ctx, -1, eventType.ToString().CString());

    if (duk_is_function(ctx, -1))
    {
        // look in the variant map cache
        duk_push_global_stash(ctx);
        duk_get_prop_index(ctx, -1, JS_GLOBALSTASH_VARIANTMAP_CACHE);
        duk_push_pointer(ctx, (void*) &eventData);
        duk_get_prop(ctx, -2);

        if (!duk_is_object(ctx, -1))
        {
            // pop result
            duk_pop(ctx);

            // we need to push a new variant map and store to cache
            // the cache object will be cleared at the send end in  the
            // global listener above
            js_push_variantmap(ctx, eventData);
            duk_push_pointer(ctx, (void*) &eventData);
            duk_dup(ctx, -2);
            duk_put_prop(ctx, -4);

        }

        duk_remove(ctx, -2); // vmap cache
        duk_remove(ctx, -2); // global stash

        if (duk_pcall(ctx, 1) != 0)
        {
            vm->SendJSErrorEvent();
        }
        else
        {
            // For widget events, need to check return value
            // and set whether handled
            if (eventType == E_WIDGETEVENT)
            {
                if (duk_is_boolean(ctx, -1))
                {
                    if (duk_to_boolean(ctx, -1))
                    {
                        eventData[WidgetEvent::P_HANDLED] = true;
                    }
                }
            }
        }
    }

    duk_set_top(ctx, top);

}