From 9781b67cf4e0474ad8be31258e7c47a7ead426db Mon Sep 17 00:00:00 2001 From: Yves Date: Sat, 21 Sep 2013 14:48:19 +0000 Subject: [PATCH] Changes the Console to expose global functions to scripts instead of properties. Fixes #2140 Refs #1886 This was SVN commit r13884. --- .../gui/common/functions_utility_list.js | 18 +-- .../gui/common/functions_utility_music.js | 8 +- .../data/mods/public/gui/session/messages.js | 4 +- .../data/mods/public/gui/session/session.js | 2 +- binaries/data/mods/public/gui/text/help.txt | 2 +- source/gui/scripting/ScriptFunctions.cpp | 2 + source/ps/GameSetup/GameSetup.cpp | 3 - source/ps/scripting/JSInterface_Console.cpp | 113 ++++-------------- source/ps/scripting/JSInterface_Console.h | 32 ++--- source/scripting/ScriptGlue.cpp | 23 ---- source/scripting/ScriptGlue.h | 1 - source/scripting/ScriptingHost.cpp | 3 - 12 files changed, 53 insertions(+), 158 deletions(-) diff --git a/binaries/data/mods/public/gui/common/functions_utility_list.js b/binaries/data/mods/public/gui/common/functions_utility_list.js index 73476e6ea8..0f3050cec6 100644 --- a/binaries/data/mods/public/gui/common/functions_utility_list.js +++ b/binaries/data/mods/public/gui/common/functions_utility_list.js @@ -11,7 +11,7 @@ function removeItem (objectName, pos) { if (getGUIObjectByName (objectName) == null) - console.write ("removeItem(): " + objectName + " not found."); + Engine.Console_Write ("removeItem(): " + objectName + " not found."); var list = getGUIObjectByName (objectName).list; var selected = getGUIObjectByName (objectName).selected; @@ -41,7 +41,7 @@ function removeItem (objectName, pos) function addItem (objectName, pos, value) { if (getGUIObjectByName (objectName) == null) - console.write ("addItem(): " + objectName + " not found."); + Engine.Console_Write ("addItem(): " + objectName + " not found."); var list = getGUIObjectByName (objectName).list; var selected = getGUIObjectByName (objectName).selected; @@ -66,7 +66,7 @@ function addItem (objectName, pos, value) function pushItem (objectName, value) { if (getGUIObjectByName (objectName) == null) - console.write ("pushItem(): " + objectName + " not found."); + Engine.Console_Write ("pushItem(): " + objectName + " not found."); var list = getGUIObjectByName (objectName).list; list.push (value); @@ -81,7 +81,7 @@ function pushItem (objectName, value) function popItem (objectName) { if (getGUIObjectByName (objectName) == null) - console.write ("popItem(): " + objectName + " not found."); + Engine.Console_Write ("popItem(): " + objectName + " not found."); var selected = getGUIObjectByName (objectName).selected; removeItem(objectName, getNumItems(objectName)-1); @@ -98,7 +98,7 @@ function popItem (objectName) function getNumItems (objectName) { if (getGUIObjectByName (objectName) == null) - console.write ("getNumItems(): " + objectName + " not found."); + Engine.Console_Write ("getNumItems(): " + objectName + " not found."); var list = getGUIObjectByName(objectName).list; return list.length; @@ -110,7 +110,7 @@ function getNumItems (objectName) function getItemValue (objectName, pos) { if (getGUIObjectByName (objectName) == null) - console.write ("getItemValue(): " + objectName + " not found."); + Engine.Console_Write ("getItemValue(): " + objectName + " not found."); var list = getGUIObjectByName(objectName).list; return list[pos]; @@ -122,7 +122,7 @@ function getItemValue (objectName, pos) function getCurrItemValue (objectName) { if (getGUIObjectByName (objectName) == null) - console.write ("getCurrItemValue(): " + objectName + " not found."); + Engine.Console_Write ("getCurrItemValue(): " + objectName + " not found."); if (getGUIObjectByName(objectName).selected == -1) return ""; @@ -137,7 +137,7 @@ function getCurrItemValue (objectName) function setCurrItemValue (objectName, string) { if (getGUIObjectByName(objectName) == null) { - console.write ("setCurrItemValue(): " + objectName + " not found."); + Engine.Console_Write ("setCurrItemValue(): " + objectName + " not found."); return -1; } @@ -157,7 +157,7 @@ function setCurrItemValue (objectName, string) } // Return -2 if failed to find value in list. - console.write ("Requested string '" + string + "' not found in " + objectName + "'s list."); + Engine.Console_Write ("Requested string '" + string + "' not found in " + objectName + "'s list."); return -2; } diff --git a/binaries/data/mods/public/gui/common/functions_utility_music.js b/binaries/data/mods/public/gui/common/functions_utility_music.js index cacc90a4aa..d21eca7b6d 100644 --- a/binaries/data/mods/public/gui/common/functions_utility_music.js +++ b/binaries/data/mods/public/gui/common/functions_utility_music.js @@ -53,7 +53,7 @@ function newRandomSound(soundType, soundSubType, soundPrePath) var soundArray = buildDirEntList(randomSoundPath, "*" + soundSubType + "*", false); if (soundArray.length == 0) { - console.write ("Failed to find sounds matching '*"+soundSubType+"*'"); + Engine.Console_Write ("Failed to find sounds matching '*"+soundSubType+"*'"); return undefined; } // Get a random number within the sound's range. @@ -64,7 +64,7 @@ function newRandomSound(soundType, soundSubType, soundPrePath) // Build path to random audio file. randomSoundPath = randomFileName; - //console.write("Playing " + randomSoundPath + " ..."); + //Engine.Console_Write("Playing " + randomSoundPath + " ..."); switch (soundType) { @@ -75,7 +75,7 @@ function newRandomSound(soundType, soundSubType, soundPrePath) return new AmbientSound(randomSoundPath); break; case "effect": - console.write("am loading effect '*"+randomSoundPath+"*'"); + Engine.Console_Write("am loading effect '*"+randomSoundPath+"*'"); break; default: break; @@ -149,7 +149,7 @@ function crossFade (outHandle, inHandle, fadeDuration) // break; // // default: -// console.write("Unrecognized ambient type: " + type); +// Engine.Console_Write("Unrecognized ambient type: " + type); // break; // } //} diff --git a/binaries/data/mods/public/gui/session/messages.js b/binaries/data/mods/public/gui/session/messages.js index 3b8c8a8bf1..63c6192b23 100644 --- a/binaries/data/mods/public/gui/session/messages.js +++ b/binaries/data/mods/public/gui/session/messages.js @@ -386,12 +386,12 @@ function addChatMessage(msg, playerAssignments) if (msg.action) { - console.write(msg.prefix + "* " + username + " " + message); + Engine.Console_Write(msg.prefix + "* " + username + " " + message); formatted = msg.prefix + "* [color=\"" + playerColor + "\"]" + username + "[/color] " + message; } else { - console.write(msg.prefix + "<" + username + "> " + message); + Engine.Console_Write(msg.prefix + "<" + username + "> " + message); formatted = msg.prefix + "<[color=\"" + playerColor + "\"]" + username + "[/color]> " + message; } break; diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js index 4e0201de11..365753e66c 100644 --- a/binaries/data/mods/public/gui/session/session.js +++ b/binaries/data/mods/public/gui/session/session.js @@ -668,7 +668,7 @@ function playRandomAmbient(type) break; default: - console.write("Unrecognized ambient type: " + type); + Engine.Console_Write("Unrecognized ambient type: " + type); break; } } diff --git a/binaries/data/mods/public/gui/text/help.txt b/binaries/data/mods/public/gui/text/help.txt index e909d572cc..8f6cb50a14 100644 --- a/binaries/data/mods/public/gui/text/help.txt +++ b/binaries/data/mods/public/gui/text/help.txt @@ -43,7 +43,7 @@ RemoveGlobalHandler( string event_name, function handler ) - Removes a global Class Timer: setTimeout( code, int time ) - time is a delay in milliseconds. When this time has elapsed, "code" is executed once. Code can be a fragment or function -Example: setTimeout( console.write("1 second passed"), 1000 ); Returns the ID of the timer (int). +Example: setTimeout( Engine.Console_Write("1 second passed"), 1000 ); Returns the ID of the timer (int). setIntervel( code, int time ) - nearly the same as setTimeout(), but "code" is executed every "time" milliseconds instead of once after a single delay. cancelIntervel() - causes all functions registered with setInterval to no longer be called. diff --git a/source/gui/scripting/ScriptFunctions.cpp b/source/gui/scripting/ScriptFunctions.cpp index 266d4ac46f..59052c507e 100644 --- a/source/gui/scripting/ScriptFunctions.cpp +++ b/source/gui/scripting/ScriptFunctions.cpp @@ -41,6 +41,7 @@ #include "ps/ProfileViewer.h" #include "ps/Pyrogenesis.h" #include "ps/SavedGame.h" +#include "ps/scripting/JSInterface_Console.h" #include "ps/UserReport.h" #include "ps/GameSetup/Atlas.h" #include "ps/GameSetup/Config.h" @@ -654,6 +655,7 @@ void GuiScriptingInit(ScriptInterface& scriptInterface) { JSI_GameView::RegisterScriptFunctions(scriptInterface); JSI_Renderer::RegisterScriptFunctions(scriptInterface); + JSI_Console::RegisterScriptFunctions(scriptInterface); // GUI manager functions: scriptInterface.RegisterFunction("GetActiveGui"); diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index c89c648e08..e2a4d9181d 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -321,9 +321,6 @@ static void RegisterJavascriptInterfaces() // maths JSI_Vector3D::init(); - // ps - JSI_Console::init(); - // GUI CGUI::ScriptingInit(); diff --git a/source/ps/scripting/JSInterface_Console.cpp b/source/ps/scripting/JSInterface_Console.cpp index f6e9900c56..4d978e9060 100644 --- a/source/ps/scripting/JSInterface_Console.cpp +++ b/source/ps/scripting/JSInterface_Console.cpp @@ -15,110 +15,47 @@ * along with 0 A.D. If not, see . */ -// JavaScript interface to native code selection and group objects - #include "precompiled.h" + +#include "scriptinterface/ScriptInterface.h" #include "JSInterface_Console.h" #include "ps/CConsole.h" -#include "scripting/JSConversions.h" +#include "ps/CLogger.h" -JSClass JSI_Console::JSI_class = -{ - "Console", 0, - JS_PropertyStub, JS_PropertyStub, - JSI_Console::getProperty, JSI_Console::setProperty, - JS_EnumerateStub, JS_ResolveStub, - JS_ConvertStub, JS_FinalizeStub, - NULL, NULL, NULL, NULL -}; - -JSPropertySpec JSI_Console::JSI_props[] = -{ - { "visible", JSI_Console::console_visible, JSPROP_ENUMERATE }, - { 0 } -}; - -JSFunctionSpec JSI_Console::JSI_methods[] = -{ - { "write", JSI_Console::writeConsole, 1, 0 }, - { 0 }, -}; - -JSBool JSI_Console::getProperty(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid id, jsval* vp) -{ - if (!JSID_IS_INT(id)) - return JS_TRUE; - - int i = JSID_TO_INT(id); - - switch (i) +bool JSI_Console::CheckGlobalInitialized() +{ + if (!g_Console) { - case console_visible: - *vp = BOOLEAN_TO_JSVAL(g_Console->IsActive()); - return JS_TRUE; - default: - *vp = JSVAL_NULL; - return JS_TRUE; + LOGERROR(L"Trying to access the console when it's not initialized!"); + return false; } + return true; } -JSBool JSI_Console::setProperty(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid id, JSBool UNUSED(strict), jsval* vp) +bool JSI_Console::GetVisibleEnabled(void* UNUSED(cbdata)) { - if (!JSID_IS_INT(id)) - return JS_TRUE; - - int i = JSID_TO_INT(id); - - switch (i) - { - case console_visible: - try - { - g_Console->SetVisible(ToPrimitive (*vp)); - return JS_TRUE; - } - catch (PSERROR_Scripting_ConversionFailed&) - { - return JS_TRUE; - } - default: - return JS_TRUE; - } + if (!CheckGlobalInitialized()) + return false; + return g_Console->IsActive(); } -void JSI_Console::init() +void JSI_Console::SetVisibleEnabled(void* UNUSED(cbdata), bool Enabled) { - g_ScriptingHost.DefineCustomObjectType(&JSI_class, NULL, 0, JSI_props, JSI_methods, NULL, NULL); + if (!CheckGlobalInitialized()) + return; + g_Console->SetVisible(Enabled); } -JSBool JSI_Console::getConsole(JSContext* cx, JSObject* UNUSED(obj), jsid UNUSED(id), jsval* vp) +void JSI_Console::Write(void* UNUSED(cbdata), std::wstring output) { - JSObject* console = JS_NewObject(cx, &JSI_Console::JSI_class, NULL, NULL); - *vp = OBJECT_TO_JSVAL(console); - return JS_TRUE; + if (!CheckGlobalInitialized()) + return; + g_Console->InsertMessage(L"%ls", output.c_str()); } -JSBool JSI_Console::writeConsole(JSContext* cx, uintN argc, jsval* vp) +void JSI_Console::RegisterScriptFunctions(ScriptInterface& scriptInterface) { - UNUSED2(cx); - - CStrW output; - for (uintN i = 0; i < argc; i++) - { - try - { - CStrW arg = g_ScriptingHost.ValueToUCString(JS_ARGV(cx, vp)[i]); - output += arg; - } - catch (PSERROR_Scripting_ConversionFailed&) - { - } - } - - // TODO: What if the console has been destroyed already? - if (g_Console) - g_Console->InsertMessage(L"%ls", output.c_str()); - - JS_SET_RVAL(cx, vp, JSVAL_VOID); - return JS_TRUE; + scriptInterface.RegisterFunction("Console_GetVisibleEnabled"); + scriptInterface.RegisterFunction("Console_SetVisibleEnabled"); + scriptInterface.RegisterFunction("Console_Write"); } diff --git a/source/ps/scripting/JSInterface_Console.h b/source/ps/scripting/JSInterface_Console.h index 8087af6a5e..6a2f56267e 100644 --- a/source/ps/scripting/JSInterface_Console.h +++ b/source/ps/scripting/JSInterface_Console.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2013 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -15,33 +15,19 @@ * along with 0 A.D. If not, see . */ -// JSInterface_Console.h -// -// The JavaScript wrapper around the console system - -#include "scripting/ScriptingHost.h" - #ifndef INCLUDED_JSI_CONSOLE #define INCLUDED_JSI_CONSOLE +class ScriptInterface; + namespace JSI_Console { - enum - { - console_visible - }; - extern JSClass JSI_class; - extern JSPropertySpec JSI_props[]; - extern JSFunctionSpec JSI_methods[]; - - JSBool getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp); - JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool strict, jsval* vp); - - JSBool getConsole(JSContext* context, JSObject* obj, jsid id, jsval* vp); - - void init(); - - JSBool writeConsole(JSContext* cx, uintN argc, jsval* vp); + bool CheckGlobalInitialized(); + bool GetVisibleEnabled(void* cbdata); + void SetVisibleEnabled(void* cbdata, bool Enabled); + void Write(void* cbdata, std::wstring output); + + void RegisterScriptFunctions(ScriptInterface& scriptInterface); } #endif diff --git a/source/scripting/ScriptGlue.cpp b/source/scripting/ScriptGlue.cpp index f946985f06..b2c73530bb 100644 --- a/source/scripting/ScriptGlue.cpp +++ b/source/scripting/ScriptGlue.cpp @@ -402,26 +402,3 @@ JSFunctionSpec ScriptFunctionTable[] = {0} }; #undef JS_FUNC - - -//----------------------------------------------------------------------------- -// property accessors -//----------------------------------------------------------------------------- - - -enum ScriptGlobalTinyIDs -{ - GLOBAL_SELECTION, - GLOBAL_GROUPSARRAY, - GLOBAL_CAMERA, - GLOBAL_CONSOLE, - GLOBAL_LIGHTENV -}; - -JSPropertySpec ScriptGlobalTable[] = -{ - { "console" , GLOBAL_CONSOLE, JSPROP_PERMANENT|JSPROP_READONLY, JSI_Console::getConsole, 0 }, - - // end of table marker - { 0, 0, 0, 0, 0 }, -}; diff --git a/source/scripting/ScriptGlue.h b/source/scripting/ScriptGlue.h index 6e0193940c..d80720f0a3 100644 --- a/source/scripting/ScriptGlue.h +++ b/source/scripting/ScriptGlue.h @@ -23,7 +23,6 @@ // referenced by ScriptingHost.cpp extern JSFunctionSpec ScriptFunctionTable[]; -extern JSPropertySpec ScriptGlobalTable[]; // dependencies (moved to header to avoid L4 warnings) // .. from main.cpp: diff --git a/source/scripting/ScriptingHost.cpp b/source/scripting/ScriptingHost.cpp index 13462c46fc..a1039ac814 100644 --- a/source/scripting/ScriptingHost.cpp +++ b/source/scripting/ScriptingHost.cpp @@ -37,9 +37,6 @@ ScriptingHost::ScriptingHost() if (!JS_DefineFunctions(m_Context, m_GlobalObject, ScriptFunctionTable)) throw PSERROR_Scripting_SetupFailed(); - - if (!JS_DefineProperties(m_Context, m_GlobalObject, ScriptGlobalTable)) - throw PSERROR_Scripting_SetupFailed(); } ScriptingHost::~ScriptingHost()