Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ScriptingHost.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2010 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "precompiled.h"
19 
20 #include <sstream>
21 
22 #include "ScriptingHost.h"
23 #include "ScriptGlue.h"
24 #include "lib/utf8.h"
25 #include "ps/Profile.h"
26 #include "ps/CLogger.h"
27 #include "ps/Filesystem.h"
29 
31 {
33 
35 
36  m_GlobalObject = JS_GetGlobalObject(m_Context);
37 
38  if (!JS_DefineFunctions(m_Context, m_GlobalObject, ScriptFunctionTable))
40 }
41 
43 {
44  delete m_ScriptInterface;
45 }
46 
48 {
49  return *m_ScriptInterface;
50 }
51 
53 {
54  // This should only be called once per process, just to clean up before
55  // we report memory leaks. (Otherwise, if it's called while there are
56  // other contexts active in other threads, things will break.)
57  JS_ShutDown();
58 }
59 
60 // filename, line and globalObject default to 0 (in which case we execute
61 // the whole script / use our m_GlobalObject)
62 void ScriptingHost::RunMemScript(const char* script, size_t size, const char* filename, int line, JSObject* globalObject)
63 {
64  if(!filename)
65  filename = "unspecified file";
66  if(!globalObject)
67  globalObject = m_GlobalObject;
68 
69  // Maybe TODO: support Unicode input formats?
70 
71  jsval rval;
72  JSBool ok = JS_EvaluateScript(m_Context, globalObject, script, (uintN)size, filename, line, &rval);
73 
74  if (ok == JS_FALSE)
76 }
77 
78 // globalObject defaults to 0 (in which case we use our m_GlobalObject).
79 void ScriptingHost::RunScript(const VfsPath& pathname, JSObject* globalObject)
80 {
81  if(!globalObject)
82  globalObject = m_GlobalObject;
83 
84  shared_ptr<u8> buf; size_t size;
85  if(g_VFS->LoadFile(pathname, buf, size) != INFO::OK) // ERRTODO: translate/pass it on
87 
88  std::wstring scriptw = wstring_from_utf8(std::string(buf.get(), buf.get() + size));
89  utf16string script(scriptw.begin(), scriptw.end());
90 
91  jsval rval;
92  JSBool ok = JS_EvaluateUCScript(m_Context, globalObject,
93  reinterpret_cast<const jschar*>(script.c_str()), (uintN)script.size(),
94  utf8_from_wstring(pathname.string()).c_str(), 1, &rval);
95 
96  if (ok == JS_FALSE)
98 }
99 
100 jsval ScriptingHost::ExecuteScript(const CStrW& script, const CStrW& calledFrom, JSObject* contextObject )
101 {
102  jsval rval;
103 
104  JSBool ok = JS_EvaluateUCScript(m_Context, contextObject ? contextObject : m_GlobalObject,
105  reinterpret_cast<const jschar*>(script.utf16().c_str()), (int)script.length(),
106  calledFrom.ToUTF8().c_str(), 1, &rval);
107 
108  if (!ok) return JSVAL_NULL;
109 
110  return rval;
111 }
112 
113 void ScriptingHost::DefineCustomObjectType(JSClass *clasp, JSNative constructor, uintN minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
114 {
115  std::string typeName = clasp->name;
116 
117  if (m_CustomObjectTypes.find(typeName) != m_CustomObjectTypes.end())
118  {
119  // This type already exists
121  }
122 
123  JSObject * obj = JS_InitClass( m_Context, m_GlobalObject, 0,
124  clasp,
125  constructor, minArgs, // Constructor, min args
126  ps, fs, // Properties, methods
127  static_ps, static_fs); // Constructor properties, methods
128 
129  if (obj == NULL)
131 
132  CustomType type;
133 
134  type.m_Object = obj;
135  type.m_Class = clasp;
136 
137  m_CustomObjectTypes[typeName] = type;
138 }
139 
140 JSObject * ScriptingHost::CreateCustomObject(const std::string & typeName)
141 {
142  std::map < std::string, CustomType > ::iterator it = m_CustomObjectTypes.find(typeName);
143 
144  if (it == m_CustomObjectTypes.end())
146 
147  return JS_ConstructObject(m_Context, (*it).second.m_Class, (*it).second.m_Object, NULL);
148 
149 }
150 
151 
152 
153 void ScriptingHost::SetObjectProperty(JSObject * object, const std::string & propertyName, jsval value)
154 {
155  JS_SetProperty(m_Context, object, propertyName.c_str(), &value);
156 }
157 
158 jsval ScriptingHost::GetObjectProperty( JSObject* object, const std::string& propertyName )
159 {
160  jsval vp;
161  JS_GetProperty( m_Context, object, propertyName.c_str(), &vp );
162  return( vp );
163 }
164 
165 
166 
167 void ScriptingHost::SetObjectProperty_Double(JSObject* object, const char* propertyName, double value)
168 {
169  jsval v;
170  if (! JS_NewNumberValue(m_Context, value, &v))
172 
173  if (! JS_SetProperty(m_Context, object, propertyName, &v))
175 }
176 
177 double ScriptingHost::GetObjectProperty_Double(JSObject* object, const char* propertyName)
178 {
179  jsval v;
180  double d;
181 
182  if (! JS_GetProperty(m_Context, object, propertyName, &v))
184  if (! JS_ValueToNumber(m_Context, v, &d))
186  return d;
187 }
188 
189 
190 
191 void ScriptingHost::SetGlobal(const std::string &globalName, jsval value)
192 {
193  JS_SetProperty(m_Context, m_GlobalObject, globalName.c_str(), &value);
194 }
195 
196 
197 
198 //----------------------------------------------------------------------------
199 // conversions
200 //----------------------------------------------------------------------------
201 
202 CStrW ScriptingHost::ValueToUCString( const jsval value )
203 {
204  JSString* string = JS_ValueToString(m_Context, value);
205  if (string == NULL)
207 
208  size_t length;
209  const jschar *strptr = JS_GetStringCharsAndLength(m_Context, string, &length);
210  if (!strptr)
212 
213  return std::wstring(strptr, strptr+length);
214 }
JSObject * CreateCustomObject(const std::string &typeName)
static void FinalShutdown()
const Status OK
Definition: status.h:386
std::string utf8_from_wstring(const std::wstring &src, Status *err)
opposite of wstring_from_utf8
Definition: utf8.cpp:208
void SetObjectProperty_Double(JSObject *object, const char *propertyName, double value)
void SetObjectProperty(JSObject *object, const std::string &propertyName, jsval value)
jsval GetObjectProperty(JSObject *object, const std::string &propertyName)
void SetGlobal(const std::string &globalName, jsval value)
Definition: path.h:75
const String & string() const
Definition: path.h:123
void RunScript(const VfsPath &filename, JSObject *globalObject=0)
std::map< std::string, CustomType > m_CustomObjectTypes
Definition: ScriptingHost.h:73
JSContext * m_Context
Definition: ScriptingHost.h:68
std::wstring wstring_from_utf8(const std::string &src, Status *err)
convert UTF-8 to a wide string (UTF-16 or UCS-4, depending on the platform&#39;s wchar_t).
Definition: utf8.cpp:225
void RunMemScript(const char *script, size_t size, const char *filename=0, int line=0, JSObject *globalObject=0)
JSFunctionSpec ScriptFunctionTable[]
Definition: ScriptGlue.cpp:372
ScriptInterface & GetScriptInterface()
std::basic_string< utf16_t, utf16_traits > utf16string
Definition: utf16string.h:109
double GetObjectProperty_Double(JSObject *object, const char *propertyName)
CStrW ValueToUCString(const jsval value)
ScriptInterface * m_ScriptInterface
Definition: ScriptingHost.h:78
Abstraction around a SpiderMonkey JSContext.
jsval ExecuteScript(const CStrW &script, const CStrW &calledFrom=L"Console", JSObject *contextObject=NULL)
PIVFS g_VFS
Definition: Filesystem.cpp:30
static shared_ptr< ScriptRuntime > CreateRuntime(int runtimeSize=DEFAULT_RUNTIME_SIZE)
Returns a runtime, which can used to initialise any number of ScriptInterfaces contexts.
JSContext * GetContext() const
void DefineCustomObjectType(JSClass *clasp, JSNative constructor, uintN nargs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
JSObject * m_GlobalObject
Definition: ScriptingHost.h:69