1
0
forked from 0ad/0ad

Console: changed things so declaring variables while an entity is selected will no longer define a new property in that entity. Kind of broke the ability to access properties of the selected object without typing selection[0], due to other bugs.

ScriptableComplex: added evil hack so iteration through properties works
with the new SpiderMonkey, which fixes the GUI scripts.

This was SVN commit r5185.
This commit is contained in:
Ykkrosh 2007-06-16 22:07:40 +00:00
parent 63732eda21
commit 73884c1f09
5 changed files with 49 additions and 26 deletions

View File

@ -63,7 +63,7 @@ JSClass GUIClass = {
//-------------------------------------------------------------------
InReaction gui_handler(const SDL_Event_* ev)
{
PROFILE(" GUI event handler ");
PROFILE( "GUI event handler" );
return g_GUI.HandleEvent(ev);
}

View File

@ -280,7 +280,7 @@ private:
* @throws PS_RESULT Depends on what pFunc might throw. PS_RESULT is standard.
* Itself doesn't throw anything.
*/
static void RecurseObject(const int RR, IGUIObject *pObject, void_Object_pFunction_argT pFunc, const T &Argument)
static void RecurseObject(int RR, IGUIObject *pObject, void_Object_pFunction_argT pFunc, const T &Argument)
{
// TODO Gee: Don't run this for the base object.
if (CheckIfRestricted(RR, pObject))
@ -301,7 +301,7 @@ private:
*
* @see RecurseObject()
*/
static void RecurseObject(const int RR, IGUIObject *pObject, void_Object_pFunction_argRefT pFunc, T &Argument)
static void RecurseObject(int RR, IGUIObject *pObject, void_Object_pFunction_argRefT pFunc, T &Argument)
{
if (CheckIfRestricted(RR, pObject))
return;
@ -321,7 +321,7 @@ private:
*
* @see RecurseObject()
*/
static void RecurseObject(const int RR, IGUIObject *pObject, void_Object_pFunction pFunc)
static void RecurseObject(int RR, IGUIObject *pObject, void_Object_pFunction pFunc)
{
if (CheckIfRestricted(RR, pObject))
return;
@ -347,7 +347,7 @@ private:
* @param pObject Object
* @return true if restricted
*/
static bool CheckIfRestricted(const int RR, IGUIObject *pObject)
static bool CheckIfRestricted(int RR, IGUIObject *pObject)
{
if (RR & GUIRR_HIDDEN)
{

View File

@ -41,6 +41,8 @@ CConsole::CConsole()
m_iMsgHistPos = 1;
m_charsPerPage=0;
m_ScriptObject = NULL; // scripting host isn't initialised yet - we'll set this later
InsertMessage(L"[ 0 A.D. Console v0.12 ] type \"\\info\" for help");
InsertMessage(L"");
@ -72,6 +74,9 @@ CConsole::~CConsole()
m_deqMsgHistory.clear();
m_deqBufHistory.clear();
delete[] m_szBuffer;
if (m_ScriptObject)
JS_RemoveRoot(g_ScriptingHost.GetContext(), &m_ScriptObject);
}
@ -666,29 +671,28 @@ void CConsole::ProcessBuffer(const wchar_t* szLine)
Iter->second();
}
}
else if (szLine[0] == ':')
else if (szLine[0] == ':' || szLine[0] == '?')
{
// Process it as JavaScript
// (Cheating) run it as the first selected entity, if there is one.
JSObject* RunAs = NULL;
if( g_Selection.m_selected.size() )
RunAs = g_Selection.m_selected[0]->GetScript();
// Run the script inside the first selected entity, if there is one.
// (Actually do it by using a separate object with the entity as its parent, so the script
// can read the entities variables but will define new variables in a private scope)
// (NOTE: this doesn't actually work, because the entities don't really have properties
// since they aren't sufficiently like real JS objects, which makes them get ignored in
// this situation. But this code is here so that it will work when the entities get fixed.)
if (! m_ScriptObject)
{
m_ScriptObject = JS_NewObject(g_ScriptingHost.GetContext(), NULL, NULL, NULL);
JS_AddRoot(g_ScriptingHost.GetContext(), &m_ScriptObject); // gets unrooted in ~CConsole
}
if (! g_Selection.m_selected.empty())
{
JS_SetParent(g_ScriptingHost.GetContext(), m_ScriptObject, g_Selection.m_selected[0]->GetScript());
}
g_ScriptingHost.ExecuteScript( CStrW( szLine + 1 ), L"Console", RunAs );
}
else if (szLine[0] == '?')
{
// Process it as JavaScript and display the result
// (Cheating) run it as the first selected entity, if there is one.
JSObject* RunAs = NULL;
if( g_Selection.m_selected.size() )
RunAs = g_Selection.m_selected[0]->GetScript();
jsval rval = g_ScriptingHost.ExecuteScript( CStrW( szLine + 1 ), L"Console", RunAs );
if (rval)
jsval rval = g_ScriptingHost.ExecuteScript( CStrW( szLine + 1 ), L"Console", m_ScriptObject );
if (szLine[0] == '?' && rval)
{
try {
InsertMessage( L"%ls", g_ScriptingHost.ValueToUCString( rval ).c_str() );
@ -696,9 +700,13 @@ void CConsole::ProcessBuffer(const wchar_t* szLine)
InsertMessage( L"%hs", "<error converting return value to string>" );
}
}
JS_SetParent(g_ScriptingHost.GetContext(), m_ScriptObject, NULL); // so the previous one can get garbage-collected
}
else
{
SendChatMessage(szLine);
}
}
void CConsole::LoadHistory()

View File

@ -21,6 +21,8 @@
#define CONSOLE_BUFFER_SIZE 1024 // for text being typed into the console
#define CONSOLE_MESSAGE_SIZE 1024 // for messages being printed into the console
struct JSObject;
typedef void(*fptr)(void);
class CConsole
@ -77,6 +79,8 @@ private:
void LoadHistory();
void SaveHistory();
JSObject* m_ScriptObject; // to run scripts in, so they can define variables that are retained between commands
public:
CConsole();

View File

@ -160,9 +160,17 @@ public:
}
// I think this is what I'm supposed to do... (cheers, Philip)
if( !JS_ValueToId( g_ScriptingHost.GetContext(), ToJSVal<CStrW>( *( it->second ) ), idp ) )
if( !JS_ValueToId( cx, ToJSVal<CStrW>( *( it->second ) ), idp ) )
return( JS_FALSE );
// EVIL HACK: since https://bugzilla.mozilla.org/show_bug.cgi?id=261887 (which is in
// the SpiderMonkey 1.6 release, and not in 1.5), you can't enumerate properties that
// don't actually exist on the object. This should probably be fixed by defining a custom
// Resolve function to make them look like they exist, but for now we just define the
// property on the object here so that it will exist by the time the JS iteration code
// does its checks.
JS_DefineProperty(cx, obj, CStr(*it->second).c_str(), JSVAL_VOID, NULL, NULL, 0);
(it->second)++;
*statep = PRIVATE_TO_JSVAL( it );
@ -604,9 +612,12 @@ JSBool CJSComplex<T, ReadOnly>::JSEnumerate( JSContext* cx, JSObject* obj, JSIte
}
// I think this is what I'm supposed to do... (cheers, Philip)
if( !JS_ValueToId( g_ScriptingHost.GetContext(), ToJSVal<CStrW>( *( it->second ) ), idp ) )
if( !JS_ValueToId( cx, ToJSVal<CStrW>( *( it->second ) ), idp ) )
return( JS_FALSE );
// EVIL HACK: see the comment in the other JSEnumerate
JS_DefineProperty(cx, obj, CStr(*it->second).c_str(), JSVAL_VOID, NULL, NULL, 0);
(it->second)++;
*statep = PRIVATE_TO_JSVAL( it );