1
0
forked from 0ad/0ad

Changes the ConfigDB to expose global functions to scripts instead of properties and custom objects.

Fixes #2172
Refs #1886

This was SVN commit r13914.
This commit is contained in:
Yves 2013-09-29 18:56:50 +00:00
parent 2ea0620abb
commit 238b7f84d8
9 changed files with 155 additions and 222 deletions

View File

@ -118,7 +118,7 @@ function crossFade (outHandle, inHandle, fadeDuration)
if (inHandle)
{
inHandle.play();
fadeIn(inHandle, g_ConfigDB.system["sound.mastergain"], fadeDuration);
fadeIn(inHandle, Engine.ConfigDB_GetValue("user", "sound.mastergain"), fadeDuration);
}
return true;
@ -168,4 +168,4 @@ function crossFade (outHandle, inHandle, fadeDuration)
//{
// var buttonSound = new Sound(BUTTON_SOUND);
// buttonSound.play();
//}
//}

View File

@ -1539,7 +1539,7 @@ var jumpCameraPositions = [], jumpCameraLast;
function jumpCamera(index)
{
var position = jumpCameraPositions[index], distanceThreshold = g_ConfigDB.system["camerajump.threshold"];
var position = jumpCameraPositions[index], distanceThreshold = Engine.ConfigDB_GetValue("user", "camerajump.threshold");
if (position)
{
if (jumpCameraLast &&

View File

@ -446,7 +446,7 @@ function setupUnitPanel(guiName, usedPanels, unitEntState, playerState, items, c
case TRAINING:
var tooltip = getEntityNamesFormatted(template);
var key = g_ConfigDB.system["hotkey.session.queueunit." + (i + 1)];
var key = Engine.ConfigDB_GetValue("user", "hotkey.session.queueunit." + (i + 1));
if (key)
tooltip = "[color=\"255 251 131\"][font=\"serif-bold-16\"][" + key + "][/font][/color] " + tooltip;

View File

@ -41,6 +41,7 @@
#include "ps/ProfileViewer.h"
#include "ps/Pyrogenesis.h"
#include "ps/SavedGame.h"
#include "ps/scripting/JSInterface_ConfigDB.h"
#include "ps/scripting/JSInterface_Console.h"
#include "ps/UserReport.h"
#include "ps/GameSetup/Atlas.h"
@ -656,6 +657,7 @@ void GuiScriptingInit(ScriptInterface& scriptInterface)
JSI_GameView::RegisterScriptFunctions(scriptInterface);
JSI_Renderer::RegisterScriptFunctions(scriptInterface);
JSI_Console::RegisterScriptFunctions(scriptInterface);
JSI_ConfigDB::RegisterScriptFunctions(scriptInterface);
// GUI manager functions:
scriptInterface.RegisterFunction<CScriptVal, &GetActiveGui>("GetActiveGui");

View File

@ -24,202 +24,16 @@
#include "ConfigDB.h"
#include "CLogger.h"
#include "Filesystem.h"
#include "scripting/ScriptingHost.h"
#include "lib/allocators/shared_ptr.h"
#include "scriptinterface/ScriptInterface.h"
typedef std::map <CStr, CConfigValueSet> TConfigMap;
TConfigMap CConfigDB::m_Map[CFG_LAST];
VfsPath CConfigDB::m_ConfigFile[CFG_LAST];
#define GET_NS_PRIVATE(cx, obj) (EConfigNamespace)((intptr_t)JS_GetPrivate(cx, obj) >> 1)
namespace ConfigNamespace_JS
{
JSBool GetProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
{
EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj);
if (cfgNs < 0 || cfgNs >= CFG_LAST)
return JS_FALSE;
jsval idval;
if (!JS_IdToValue(cx, id, &idval))
return JS_FALSE;
std::string propName;
if (!ScriptInterface::FromJSVal(cx, idval, propName))
return JS_FALSE;
CConfigValue *val = g_ConfigDB.GetValue(cfgNs, propName);
if (val)
{
JSString *js_str = JS_NewStringCopyN(cx, val->m_String.c_str(), val->m_String.size());
*vp = STRING_TO_JSVAL(js_str);
}
return JS_TRUE;
}
JSBool SetProperty(JSContext* cx, JSObject* obj, jsid id, JSBool UNUSED(strict), jsval* vp)
{
EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj);
if (cfgNs < 0 || cfgNs >= CFG_LAST)
return JS_FALSE;
jsval idval;
if (!JS_IdToValue(cx, id, &idval))
return JS_FALSE;
std::string propName;
if (!ScriptInterface::FromJSVal(cx, idval, propName))
return JS_FALSE;
CConfigValue *val = g_ConfigDB.CreateValue(cfgNs, propName);
if (!ScriptInterface::FromJSVal(cx, *vp, val->m_String))
return JS_FALSE;
return JS_TRUE;
}
JSClass Class = {
"ConfigNamespace", JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub,
GetProperty, SetProperty,
JS_EnumerateStub, JS_ResolveStub,
JS_ConvertStub, JS_FinalizeStub
};
JSBool Construct(JSContext* cx, uintN argc, jsval* vp)
{
UNUSED2(argc);
JSObject *newObj = JS_NewObject(cx, &Class, NULL, NULL);
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObj));
return JS_TRUE;
}
void SetNamespace(JSContext *cx, JSObject *obj, EConfigNamespace cfgNs)
{
JS_SetPrivate(cx, obj, (void *)((uintptr_t)cfgNs << 1)); // JS requires bottom bit = 0
}
JSBool WriteFile(JSContext* cx, uintN argc, jsval* vp)
{
EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, JS_THIS_OBJECT(cx, vp));
if (cfgNs < 0 || cfgNs >= CFG_LAST)
return JS_FALSE;
if (argc != 1)
return JS_FALSE;
VfsPath path;
if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], path))
return JS_FALSE;
bool res = g_ConfigDB.WriteFile(cfgNs, path);
JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(res));
return JS_TRUE;
}
JSBool Reload(JSContext* cx, uintN argc, jsval* vp)
{
if (argc != 0)
return JS_FALSE;
EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, JS_THIS_OBJECT(cx, vp));
if (cfgNs < 0 || cfgNs >= CFG_LAST)
return JS_FALSE;
JSBool ret = g_ConfigDB.Reload(cfgNs);
JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(ret));
return JS_TRUE;
}
JSBool SetFile(JSContext* cx, uintN argc, jsval* vp)
{
EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, JS_THIS_OBJECT(cx, vp));
if (cfgNs < 0 || cfgNs >= CFG_LAST)
return JS_FALSE;
if (argc != 1)
return JS_FALSE;
VfsPath path;
if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], path))
return JS_FALSE;
g_ConfigDB.SetConfigFile(cfgNs, path);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}
JSFunctionSpec Funcs[] = {
{ "writeFile", WriteFile, 2, 0 },
{ "reload", Reload, 0, 0 },
{ "setFile", SetFile, 2, 0 },
{0}
};
};
namespace ConfigDB_JS
{
JSClass Class = {
"ConfigDB", 0,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub,
JS_ConvertStub, JS_FinalizeStub
};
JSPropertySpec Props[] = {
{0}
};
JSFunctionSpec Funcs[] = {
{0}
};
JSBool Construct(JSContext* cx, uintN argc, jsval* vp)
{
UNUSED2(argc);
JSObject *newObj = JS_NewObject(cx, &Class, NULL, NULL);
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObj));
int flags=JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT;
#define cfg_ns(_propname, _enum) STMT (\
JSObject *nsobj=g_ScriptingHost.CreateCustomObject("ConfigNamespace"); \
ENSURE(nsobj); \
ConfigNamespace_JS::SetNamespace(cx, nsobj, _enum); \
ENSURE(JS_DefineProperty(cx, newObj, _propname, OBJECT_TO_JSVAL(nsobj), NULL, NULL, flags)); )
cfg_ns("default", CFG_DEFAULT);
cfg_ns("system", CFG_SYSTEM);
cfg_ns("user", CFG_USER);
cfg_ns("mod", CFG_MOD);
#undef cfg_ns
return JS_TRUE;
}
};
CConfigDB::CConfigDB()
{
}
void CConfigDB::RegisterJSConfigDB()
{
g_ScriptingHost.DefineCustomObjectType(&ConfigDB_JS::Class, ConfigDB_JS::Construct, 0, ConfigDB_JS::Props, ConfigDB_JS::Funcs, NULL, NULL);
g_ScriptingHost.DefineCustomObjectType(&ConfigNamespace_JS::Class, ConfigNamespace_JS::Construct, 0, NULL, ConfigNamespace_JS::Funcs, NULL, NULL);
JSObject *js_ConfigDB = g_ScriptingHost.CreateCustomObject("ConfigDB");
g_ScriptingHost.SetGlobal("g_ConfigDB", OBJECT_TO_JSVAL(js_ConfigDB));
}
CConfigValue *CConfigDB::GetValue(EConfigNamespace ns, const CStr& name)
{
CConfigValueSet* values = GetValues(ns, name);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2012 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
@ -21,30 +21,7 @@
TDD : http://www.wildfiregames.com/forum/index.php?showtopic=1125
OVERVIEW:
JavaScript:
All the javascript interfaces are provided through the global object
g_ConfigDB.
g_ConfigDB Properties:
system:
All CFG_SYSTEM values are linked to properties of this object.
a=g_ConfigDB.system.foo; is equivalent to C++ code
g_ConfigDB.GetValue(CFG_SYSTEM, "foo");
mod: Ditto, but linked to CFG_MOD
user: Ditto, but linked to CFG_USER
default: Ditto, but linked to CFG_DEFAULT
g_ConfigDB Functions: None so far
ConfigNamespace Functions: (applicable to the system, mod or user
properties of g_ConfigDB)
boolean WriteFile(boolean useVFS, string path):
JS interface to g_ConfigDB.WriteFile - should work exactly the
same.
boolean Reload() => g_ConfigDB.Reload()
void SetFile() => g_ConfigDB.SetConfigFile()
JavaScript: Check this documentation: http://trac.wildfiregames.com/wiki/Exposed_ConfigDB_Functions
*/
#ifndef INCLUDED_CONFIGDB
@ -81,11 +58,6 @@ class CConfigDB: public Singleton<CConfigDB>
public:
CConfigDB();
// NOTE: Construct the Singleton Object *after* JavaScript init, so that
// the JS interface can be registered. ConfigDB (C++) needs to be initialized before
// The ScriptInterface because the ScriptInterface requires some configuration information too.
void RegisterJSConfigDB();
/**
* Attempt to find a config variable with the given name; will search

View File

@ -919,8 +919,6 @@ void Init(const CmdLineArgs& args, int flags)
InitScripting(); // before GUI
g_ConfigDB.RegisterJSConfigDB(); // after scripting
// Optionally start profiler HTTP output automatically
// (By default it's only enabled by a hotkey, for security/performance)
bool profilerHTTPEnable = false;

View File

@ -0,0 +1,111 @@
/* 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
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precompiled.h"
#include "JSInterface_ConfigDB.h"
#include "ps/ConfigDB.h"
#include "ps/CLogger.h"
#include "scriptinterface/ScriptInterface.h"
bool JSI_ConfigDB::GetConfigNamespace(std::wstring cfgNsString, EConfigNamespace& cfgNs)
{
if (cfgNsString == L"default")
cfgNs = CFG_DEFAULT;
else if (cfgNsString == L"system")
cfgNs = CFG_SYSTEM;
else if (cfgNsString == L"user")
cfgNs = CFG_USER;
else if (cfgNsString == L"mod")
cfgNs = CFG_MOD;
else
{
LOGERROR(L"Invalid namespace name passed to the ConfigDB!");
return false;
}
return true;
}
std::string JSI_ConfigDB::GetValue(void* UNUSED(cbdata), std::wstring cfgNsString, std::string name)
{
EConfigNamespace cfgNs;
if (!GetConfigNamespace(cfgNsString, cfgNs))
return std::string();
CConfigValue *val = g_ConfigDB.GetValue(cfgNs, name);
if (val)
{
return val->m_String;
}
else
{
LOGWARNING(L"Config setting %hs does not exist!", name.c_str());
return std::string();
}
}
bool JSI_ConfigDB::CreateValue(void* UNUSED(cbdata), std::wstring cfgNsString, std::string name, std::string value)
{
EConfigNamespace cfgNs;
if (!GetConfigNamespace(cfgNsString, cfgNs))
return false;
CConfigValue *val = g_ConfigDB.CreateValue(cfgNs, name);
val->m_String = value;
return true;
}
bool JSI_ConfigDB::WriteFile(void* UNUSED(cbdata), std::wstring cfgNsString, Path path)
{
EConfigNamespace cfgNs;
if (!GetConfigNamespace(cfgNsString, cfgNs))
return false;
bool ret = g_ConfigDB.WriteFile(cfgNs, path);
return ret;
}
bool JSI_ConfigDB::Reload(void* UNUSED(cbdata), std::wstring cfgNsString)
{
EConfigNamespace cfgNs;
if (!GetConfigNamespace(cfgNsString, cfgNs))
return false;
bool ret = g_ConfigDB.Reload(cfgNs);
return ret;
}
bool JSI_ConfigDB::SetFile(void* UNUSED(cbdata), std::wstring cfgNsString, Path path)
{
EConfigNamespace cfgNs;
if (!GetConfigNamespace(cfgNsString, cfgNs))
return false;
g_ConfigDB.SetConfigFile(cfgNs, path);
return true;
}
void JSI_ConfigDB::RegisterScriptFunctions(ScriptInterface& scriptInterface)
{
scriptInterface.RegisterFunction<std::string, std::wstring, std::string, &JSI_ConfigDB::GetValue>("ConfigDB_GetValue");
scriptInterface.RegisterFunction<bool, std::wstring, std::string, std::string, &JSI_ConfigDB::CreateValue>("ConfigDB_CreateValue");
scriptInterface.RegisterFunction<bool, std::wstring, Path, &JSI_ConfigDB::WriteFile>("ConfigDB_WriteFile");
scriptInterface.RegisterFunction<bool, std::wstring, Path, &JSI_ConfigDB::SetFile>("ConfigDB_SetFile");
scriptInterface.RegisterFunction<bool, std::wstring, &JSI_ConfigDB::Reload>("ConfigDB_Reload");
}

View File

@ -0,0 +1,36 @@
/* 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
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_JSI_CONFIGDB
#define INCLUDED_JSI_CONFIGDB
#include "ps/ConfigDB.h"
class ScriptInterface;
namespace JSI_ConfigDB
{
bool GetConfigNamespace(std::wstring cfgNsString, EConfigNamespace& cfgNs);
std::string GetValue(void* cbdata, std::wstring cfgNsString, std::string name);
bool CreateValue(void* cbdata, std::wstring cfgNsString, std::string name, std::string value);
bool WriteFile(void* cbdata, std::wstring cfgNsString, Path path);
bool Reload(void* cbdata, std::wstring cfgNsString);
bool SetFile(void* cbdata, std::wstring cfgNsString, Path path);
void RegisterScriptFunctions(ScriptInterface& scriptInterface);
}
#endif