JS Interface to entities. It even partially works now.
This was SVN commit r469.
This commit is contained in:
parent
663f25f6b6
commit
e4fe4ed602
@ -1,5 +1,4 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "ogl.h"
|
||||
#include "res/tex.h"
|
||||
#include "TextureEntry.h"
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <string>
|
||||
|
||||
// block := power-of-two sized chunk of a file.
|
||||
|
@ -42,10 +42,14 @@
|
||||
#include "PathfindEngine.h"
|
||||
#include "XML.h"
|
||||
|
||||
#include "ConfigDB.h"
|
||||
#include "scripting/JSInterface_Entity.h"
|
||||
#include "scripting/JSInterface_BaseEntity.h"
|
||||
#include "scripting/JSInterface_Vector3D.h"
|
||||
|
||||
#include "ConfigDB.h"
|
||||
#include "CLogger.h"
|
||||
|
||||
|
||||
#ifndef NO_GUI
|
||||
#include "gui/GUI.h"
|
||||
#endif
|
||||
@ -431,7 +435,7 @@ void ParseArgs(int argc, char* argv[])
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
g_EntGraph = true;
|
||||
g_EntGraph = true; break;
|
||||
case 'v':
|
||||
g_VSync = true;
|
||||
break;
|
||||
@ -622,7 +626,7 @@ PREVTSC=TSC;
|
||||
|
||||
font = font_load("fonts/verdana.fnt");
|
||||
|
||||
g_Console = new CConsole(0, g_yres-600.f, 800.f, 600.f);
|
||||
g_Console = new CConsole(0, g_yres-600.f, g_xres, 600.f);
|
||||
|
||||
// create renderer
|
||||
new CRenderer;
|
||||
@ -653,6 +657,10 @@ PREVTSC=TSC;
|
||||
|
||||
g_EntityTemplateCollection.loadTemplates();
|
||||
|
||||
// Register the JavaScript interfaces with the runtime
|
||||
JSI_Entity::init();
|
||||
JSI_BaseEntity::init();
|
||||
JSI_Vector3D::init();
|
||||
|
||||
// if no map name specified, load test01.pmp (for convenience during
|
||||
// development. that means loading no map at all is currently impossible.
|
||||
|
@ -22,7 +22,7 @@ class CVector3D
|
||||
float X, Y, Z;
|
||||
|
||||
public:
|
||||
CVector3D () { }
|
||||
CVector3D () { X = 0.0f; Y = 0.0f; Z = 0.0f; }
|
||||
CVector3D (float x, float y, float z);
|
||||
|
||||
int operator ! () const ;
|
||||
|
138
source/maths/scripting/JSInterface_Vector3D.cpp
Executable file
138
source/maths/scripting/JSInterface_Vector3D.cpp
Executable file
@ -0,0 +1,138 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "JSInterface_Vector3D.h"
|
||||
|
||||
JSClass JSI_Vector3D::JSI_class = {
|
||||
"Vector3D", JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JSI_Vector3D::getProperty, JSI_Vector3D::setProperty,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JS_ConvertStub, JSI_Vector3D::finalize,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
JSPropertySpec JSI_Vector3D::JSI_props[] =
|
||||
{
|
||||
{ "x", JSI_Vector3D::component_x, JSPROP_ENUMERATE },
|
||||
{ "y", JSI_Vector3D::component_y, JSPROP_ENUMERATE },
|
||||
{ "z", JSI_Vector3D::component_z, JSPROP_ENUMERATE },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSFunctionSpec JSI_Vector3D::JSI_methods[] =
|
||||
{
|
||||
{ "toString", JSI_Vector3D::toString, 0, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
void JSI_Vector3D::init()
|
||||
{
|
||||
g_ScriptingHost.DefineCustomObjectType( &JSI_class, JSI_Vector3D::construct, 0, JSI_props, JSI_methods, NULL, NULL );
|
||||
}
|
||||
|
||||
JSI_Vector3D::Vector3D_Info::Vector3D_Info()
|
||||
{
|
||||
owner = NULL;
|
||||
vector = new CVector3D();
|
||||
}
|
||||
|
||||
JSI_Vector3D::Vector3D_Info::Vector3D_Info( float x, float y, float z )
|
||||
{
|
||||
owner = NULL;
|
||||
vector = new CVector3D( x, y, z );
|
||||
}
|
||||
|
||||
JSI_Vector3D::Vector3D_Info::Vector3D_Info( CVector3D* copy, IPropertyOwner* _owner )
|
||||
{
|
||||
owner = _owner;
|
||||
updateFn = NULL;
|
||||
vector = copy;
|
||||
}
|
||||
|
||||
JSI_Vector3D::Vector3D_Info::Vector3D_Info( CVector3D* copy, IPropertyOwner* _owner, void( IPropertyOwner::*_updateFn )(void) )
|
||||
{
|
||||
owner = _owner;
|
||||
updateFn = _updateFn;
|
||||
vector = copy;
|
||||
}
|
||||
|
||||
JSI_Vector3D::Vector3D_Info::~Vector3D_Info()
|
||||
{
|
||||
if( !owner ) delete( vector );
|
||||
}
|
||||
|
||||
JSBool JSI_Vector3D::getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
|
||||
{
|
||||
if( !JSVAL_IS_INT( id ) )
|
||||
return( JS_TRUE );
|
||||
|
||||
Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetPrivate( cx, obj );
|
||||
if( !vectorInfo ) return( JS_TRUE );
|
||||
CVector3D* vectorData = vectorInfo->vector;
|
||||
|
||||
switch( g_ScriptingHost.ValueToInt( id ) )
|
||||
{
|
||||
case component_x: *vp = DOUBLE_TO_JSVAL( JS_NewDouble( cx, vectorData->X ) ); return( JS_TRUE );
|
||||
case component_y: *vp = DOUBLE_TO_JSVAL( JS_NewDouble( cx, vectorData->Y ) ); return( JS_TRUE );
|
||||
case component_z: *vp = DOUBLE_TO_JSVAL( JS_NewDouble( cx, vectorData->Z ) ); return( JS_TRUE );
|
||||
}
|
||||
|
||||
return( JS_FALSE );
|
||||
}
|
||||
|
||||
JSBool JSI_Vector3D::setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
|
||||
{
|
||||
if( !JSVAL_IS_INT( id ) )
|
||||
return( JS_TRUE );
|
||||
|
||||
Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetPrivate( cx, obj );
|
||||
if( !vectorInfo ) return( JS_TRUE );
|
||||
CVector3D* vectorData = vectorInfo->vector;
|
||||
|
||||
switch( g_ScriptingHost.ValueToInt( id ) )
|
||||
{
|
||||
case component_x: vectorData->X = (float)g_ScriptingHost.ValueToDouble( *vp ); break;
|
||||
case component_y: vectorData->Y = (float)g_ScriptingHost.ValueToDouble( *vp ); break;
|
||||
case component_z: vectorData->Z = (float)g_ScriptingHost.ValueToDouble( *vp ); break;
|
||||
}
|
||||
|
||||
if( vectorInfo->owner && vectorInfo->updateFn ) ( (vectorInfo->owner)->*(vectorInfo->updateFn) )();
|
||||
|
||||
return( JS_TRUE );
|
||||
return( JS_FALSE );
|
||||
}
|
||||
|
||||
JSBool JSI_Vector3D::construct( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
if( ( argc != 0 ) && ( argc != 3 ) ) return( JS_FALSE );
|
||||
if( argc == 0 )
|
||||
{
|
||||
JS_SetPrivate( cx, obj, new Vector3D_Info() );
|
||||
return( JS_TRUE );
|
||||
}
|
||||
else if( argc == 3 )
|
||||
{
|
||||
float x = (float)g_ScriptingHost.ValueToDouble( argv[0] );
|
||||
float y = (float)g_ScriptingHost.ValueToDouble( argv[1] );
|
||||
float z = (float)g_ScriptingHost.ValueToDouble( argv[2] );
|
||||
JS_SetPrivate( cx, obj, new Vector3D_Info( x, y, z ) );
|
||||
}
|
||||
return( JS_TRUE );
|
||||
}
|
||||
|
||||
void JSI_Vector3D::finalize( JSContext* cx, JSObject* obj )
|
||||
{
|
||||
delete( JS_GetPrivate( cx, obj ) );
|
||||
}
|
||||
|
||||
JSBool JSI_Vector3D::toString( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
char buffer[256];
|
||||
Vector3D_Info* vectorInfo = (Vector3D_Info*)JS_GetPrivate( cx, obj );
|
||||
if( !vectorInfo ) return( JS_TRUE );
|
||||
CVector3D* vectorData = vectorInfo->vector;
|
||||
snprintf( buffer, 256, "[object Vector3D: ( %f, %f, %f )]", vectorData->X, vectorData->Y, vectorData->Z );
|
||||
buffer[255] = 0;
|
||||
*rval = STRING_TO_JSVAL( JS_NewStringCopyZ( cx, buffer ) );
|
||||
return( JS_TRUE );
|
||||
}
|
49
source/maths/scripting/JSInterface_Vector3D.h
Executable file
49
source/maths/scripting/JSInterface_Vector3D.h
Executable file
@ -0,0 +1,49 @@
|
||||
// JSInterface_Entity.h
|
||||
//
|
||||
// Last modified: 03 June 04, Mark Thompson mot20@cam.ac.uk / mark@wildfiregames.com
|
||||
//
|
||||
// A JavaScript class representing a Prometheus CVector3D object.
|
||||
//
|
||||
// Usage: Used when manipulating objects of class 'Vector3D' in JavaScript.
|
||||
//
|
||||
// Mark Thompson mot20@cam.ac.uk / mark@wildfiregames.com
|
||||
|
||||
#include "scripting/ScriptingHost.h"
|
||||
#include "Vector3D.h"
|
||||
|
||||
#ifndef JSI_VECTOR3_INCLUDED
|
||||
#define JSI_VECTOR3_INCLUDED
|
||||
|
||||
class IPropertyOwner;
|
||||
|
||||
namespace JSI_Vector3D
|
||||
{
|
||||
enum
|
||||
{
|
||||
component_x,
|
||||
component_y,
|
||||
component_z
|
||||
};
|
||||
JSBool toString( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
|
||||
struct Vector3D_Info
|
||||
{
|
||||
IPropertyOwner* owner;
|
||||
void ( IPropertyOwner::*updateFn )();
|
||||
CVector3D* vector;
|
||||
Vector3D_Info();
|
||||
Vector3D_Info( float x, float y, float z );
|
||||
Vector3D_Info( CVector3D* copy, IPropertyOwner* _owner );
|
||||
Vector3D_Info( CVector3D* copy, IPropertyOwner* _owner, void (IPropertyOwner::*_updateFn)() );
|
||||
~Vector3D_Info();
|
||||
};
|
||||
extern JSClass JSI_class;
|
||||
extern JSPropertySpec JSI_props[];
|
||||
extern JSFunctionSpec JSI_methods[];
|
||||
JSBool getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
|
||||
JSBool setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
|
||||
void finalize( JSContext* cx, JSObject* obj );
|
||||
JSBool construct( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
|
||||
void init();
|
||||
};
|
||||
|
||||
#endif
|
@ -5,6 +5,8 @@
|
||||
#include "Prometheus.h"
|
||||
#include "sysdep/sysdep.h"
|
||||
|
||||
#include "scripting/ScriptingHost.h"
|
||||
|
||||
CConsole::CConsole(float X, float Y, float W, float H)
|
||||
: m_fX(X), m_fY(Y), m_fWidth(W), m_fHeight(H)
|
||||
{
|
||||
@ -242,7 +244,7 @@ void CConsole::DrawCursor(void)
|
||||
|
||||
|
||||
//Inserts a character into the buffer.
|
||||
void CConsole::InsertChar(const int szChar)
|
||||
void CConsole::InsertChar(const int szChar, const int cooked )
|
||||
{
|
||||
static int iHistoryPos = -1;
|
||||
|
||||
@ -321,15 +323,16 @@ void CConsole::InsertChar(const int szChar)
|
||||
|
||||
default: //Insert a character
|
||||
if (IsFull()) return;
|
||||
if (!isprint(szChar)) return;
|
||||
if( cooked >= 255 ) return;
|
||||
if (!isprint( cooked )) return;
|
||||
|
||||
if (IsEOB()) //are we at the end of the buffer?
|
||||
m_szBuffer[m_iBufferPos] = szChar; //cat char onto end
|
||||
m_szBuffer[m_iBufferPos] = cooked; //cat char onto end
|
||||
else{ //we need to insert
|
||||
int i;
|
||||
for(i=m_iBufferLength; i>m_iBufferPos; i--)
|
||||
m_szBuffer[i] = m_szBuffer[i-1]; // move chars to right
|
||||
m_szBuffer[i] = szChar;
|
||||
m_szBuffer[i] = cooked;
|
||||
}
|
||||
|
||||
m_iBufferPos++;
|
||||
@ -410,6 +413,18 @@ void CConsole::ProcessBuffer(const char* szLine){
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( szLine[0] == ':' )
|
||||
{
|
||||
// Process it as JavaScript
|
||||
g_ScriptingHost.ExecuteScript( szLine + 1 );
|
||||
}
|
||||
else if( szLine[0] == '?' )
|
||||
{
|
||||
// Process it as JavaScript and display the result
|
||||
jsval rval = g_ScriptingHost.ExecuteScript( szLine + 1 );
|
||||
if( rval )
|
||||
InsertMessage( g_ScriptingHost.ValueToString( rval ).c_str() );
|
||||
}
|
||||
else InsertMessage("<say>: %s", szLine);
|
||||
|
||||
delete[] szCommand;
|
||||
@ -425,6 +440,6 @@ bool conInputHandler(const SDL_Event& ev)
|
||||
if(ev.type != SDL_KEYDOWN)
|
||||
return false;
|
||||
|
||||
g_Console->InsertChar(ev.key.keysym.sym);
|
||||
g_Console->InsertChar(ev.key.keysym.sym, ev.key.keysym.unicode );
|
||||
return g_Console->IsActive();
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
#ifndef CCONSOLE_H
|
||||
#define CCONSOLE_H
|
||||
|
||||
#define BUFFER_SIZE 50
|
||||
#define BUFFER_SIZE 100
|
||||
#define FONT_HEIGHT 18
|
||||
|
||||
typedef void(*fptr)(void);
|
||||
@ -70,7 +70,7 @@ public:
|
||||
void Render();
|
||||
|
||||
void InsertMessage(const char* szMessage, ...);
|
||||
void InsertChar(const int szChar);
|
||||
void InsertChar(const int szChar, const int cooked);
|
||||
|
||||
void SetBuffer(const char* szMessage, ...);
|
||||
void FlushBuffer();
|
||||
@ -80,4 +80,7 @@ public:
|
||||
bool IsActive() { return m_bVisible; }
|
||||
};
|
||||
|
||||
// TODO MT: Better solution to character translation than 'const int cooked'? Anyone?
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -193,7 +193,7 @@ public:
|
||||
virtual u8 *Serialize(u8 *buffer) const;
|
||||
virtual const u8 *Deserialize(const u8 *buffer, const u8 *bufferend);
|
||||
|
||||
private:
|
||||
protected:
|
||||
tstring m_String;
|
||||
TCHAR m_ConversionBuffer[CONVERSION_BUFFER_SIZE];
|
||||
};
|
||||
|
@ -5,6 +5,7 @@
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "ogl.h"
|
||||
#include "Renderer.h"
|
||||
|
@ -5,6 +5,7 @@
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "precompiled.h"
|
||||
#include <assert.h>
|
||||
#include "ogl.h"
|
||||
|
@ -1,6 +1,17 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "ScriptGlue.h"
|
||||
#include "CConsole.h"
|
||||
#include "CStr.h"
|
||||
#include "EntityHandles.h"
|
||||
#include "Entity.h"
|
||||
#include "EntityManager.h"
|
||||
#include "BaseEntityCollection.h"
|
||||
#include "scripting/JSInterface_Entity.h"
|
||||
#include "scripting/JSInterface_BaseEntity.h"
|
||||
#include "scripting/JSInterface_Vector3D.h"
|
||||
|
||||
extern CConsole* g_Console;
|
||||
|
||||
// Parameters for the table are:
|
||||
|
||||
@ -12,7 +23,9 @@
|
||||
JSFunctionSpec ScriptFunctionTable[] =
|
||||
{
|
||||
{"WriteLog", WriteLog, 1, 0, 0},
|
||||
|
||||
{"writeConsole", writeConsole, 1, 0, 0 },
|
||||
{"getEntityByHandle", getEntityByHandle, 1, 0, 0 },
|
||||
{"getEntityTemplate", getEntityTemplate, 1, 0, 0 },
|
||||
{0, 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
@ -47,3 +60,62 @@ JSBool WriteLog(JSContext * context, JSObject * globalObject, unsigned int argc,
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool writeConsole( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
assert( argc >= 1 );
|
||||
CStr output = g_ScriptingHost.ValueToString( argv[0] );
|
||||
g_Console->InsertMessage( output );
|
||||
return( JS_TRUE );
|
||||
}
|
||||
|
||||
JSBool getEntityByHandle( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
assert( argc >= 1 );
|
||||
i32 handle;
|
||||
try
|
||||
{
|
||||
handle = g_ScriptingHost.ValueToInt( argv[0] );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
*rval = JSVAL_NULL;
|
||||
return( JS_TRUE );
|
||||
}
|
||||
HEntity* v = g_EntityManager.getByHandle( (u16)handle );
|
||||
if( !v )
|
||||
{
|
||||
*rval = JSVAL_NULL;
|
||||
return( JS_TRUE );
|
||||
}
|
||||
JSObject* entity = JS_NewObject( context, &JSI_Entity::JSI_class, NULL, NULL );
|
||||
JS_SetPrivate( context, entity, v );
|
||||
*rval = OBJECT_TO_JSVAL( entity );
|
||||
return( JS_TRUE );
|
||||
}
|
||||
|
||||
JSBool getEntityTemplate( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
assert( argc >= 1 );
|
||||
CStr templateName;
|
||||
try
|
||||
{
|
||||
templateName = g_ScriptingHost.ValueToString( argv[0] );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
*rval = JSVAL_NULL;
|
||||
return( JS_TRUE );
|
||||
}
|
||||
CBaseEntity* v = g_EntityTemplateCollection.getTemplate( templateName );
|
||||
if( !v )
|
||||
{
|
||||
*rval = JSVAL_NULL;
|
||||
return( JS_TRUE );
|
||||
}
|
||||
JSObject* baseEntity = JS_NewObject( context, &JSI_BaseEntity::JSI_class, NULL, NULL );
|
||||
JS_SetPrivate( context, baseEntity, v );
|
||||
*rval = OBJECT_TO_JSVAL( baseEntity );
|
||||
return( JS_TRUE );
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,10 @@
|
||||
|
||||
JSBool WriteLog(JSContext * context, JSObject * globalObject, unsigned int argc, jsval *argv, jsval *rval);
|
||||
|
||||
JSBool writeConsole( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval );
|
||||
JSBool getEntityByHandle( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval );
|
||||
JSBool getEntityTemplate( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval );
|
||||
|
||||
extern JSFunctionSpec ScriptFunctionTable[];
|
||||
|
||||
#endif
|
||||
|
@ -2,12 +2,16 @@
|
||||
|
||||
#include "ScriptingHost.h"
|
||||
#include "ScriptGlue.h"
|
||||
#include "CConsole.h"
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "float.h" // <- MT: Just for _finite(), converting certain strings was causing wierd bugs.
|
||||
|
||||
#pragma comment (lib, "js32.lib")
|
||||
|
||||
extern CConsole* g_Console;
|
||||
|
||||
namespace
|
||||
{
|
||||
const int RUNTIME_MEMORY_ALLOWANCE = 16 * 1024 * 1024;
|
||||
@ -76,6 +80,11 @@ ScriptingHost::~ScriptingHost()
|
||||
}
|
||||
}
|
||||
|
||||
JSContext* ScriptingHost::getContext()
|
||||
{
|
||||
return( m_Context );
|
||||
}
|
||||
|
||||
void ScriptingHost::LoadScriptFromDisk(const std::string & fileName)
|
||||
{
|
||||
std::string script;
|
||||
@ -124,6 +133,8 @@ jsval ScriptingHost::ExecuteScript(const std::string & script)
|
||||
|
||||
JSBool ok = JS_EvaluateScript(m_Context, m_GlobalObject, script.c_str(), (int)script.length(), "Console", 0, &rval);
|
||||
|
||||
if( !ok ) return( NULL );
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
@ -223,6 +234,13 @@ void ScriptingHost::SetObjectProperty(JSObject * object, const std::string & pro
|
||||
JS_SetProperty(m_Context, object, propertyName.c_str(), &value);
|
||||
}
|
||||
|
||||
jsval ScriptingHost::GetObjectProperty( JSObject* object, const std::string& propertyName )
|
||||
{
|
||||
jsval vp;
|
||||
JS_GetProperty( m_Context, object, propertyName.c_str(), &vp );
|
||||
return( vp );
|
||||
}
|
||||
|
||||
int ScriptingHost::ValueToInt(const jsval value)
|
||||
{
|
||||
int32 i = 0;
|
||||
@ -264,7 +282,7 @@ double ScriptingHost::ValueToDouble(const jsval value)
|
||||
|
||||
JSBool ok = JS_ValueToNumber(m_Context, value, &d);
|
||||
|
||||
if (ok == JS_FALSE)
|
||||
if (ok == JS_FALSE || !_finite( d ) )
|
||||
{
|
||||
throw (std::string("Convert to double failed"));
|
||||
}
|
||||
@ -274,6 +292,14 @@ double ScriptingHost::ValueToDouble(const jsval value)
|
||||
|
||||
void ScriptingHost::ErrorReporter(JSContext * context, const char * message, JSErrorReport * report)
|
||||
{
|
||||
g_Console->InsertMessage( "%s ( %d )", report->filename, report->lineno );
|
||||
if( message )
|
||||
{
|
||||
g_Console->InsertMessage( message );
|
||||
}
|
||||
else
|
||||
g_Console->InsertMessage( "No error message available" );
|
||||
|
||||
if (report->filename != NULL)
|
||||
{
|
||||
std::cout << report->filename << " (" << report->lineno << ") ";
|
||||
|
@ -49,6 +49,8 @@ public:
|
||||
ScriptingHost();
|
||||
~ScriptingHost();
|
||||
|
||||
JSContext* getContext();
|
||||
|
||||
void LoadScriptFromDisk(const std::string & fileName);
|
||||
|
||||
jsval CallFunction(const std::string & functionName, jsval * params, int numParams);
|
||||
@ -65,6 +67,7 @@ public:
|
||||
JSObject * CreateCustomObject(const std::string & typeName);
|
||||
|
||||
void SetObjectProperty(JSObject * object, const std::string & propertyName, jsval value);
|
||||
jsval GetObjectProperty( JSObject* object, const std::string& propertyName );
|
||||
|
||||
int ValueToInt(const jsval value);
|
||||
bool ValueToBool(const jsval value);
|
||||
|
@ -9,21 +9,16 @@
|
||||
// automatically use namespace ..
|
||||
XERCES_CPP_NAMESPACE_USE
|
||||
|
||||
CBaseEntity::CBaseEntity( const CBaseEntity& copy )
|
||||
CBaseEntity::CBaseEntity()
|
||||
{
|
||||
m_actorObject = copy.m_actorObject;
|
||||
|
||||
m_name = copy.m_name;
|
||||
m_bound_type = copy.m_bound_type;
|
||||
m_speed = copy.m_speed;
|
||||
m_turningRadius = copy.m_turningRadius;
|
||||
m_base = NULL;
|
||||
m_base.associate( this, "super" );
|
||||
m_name.associate( this, "name" );
|
||||
m_speed.associate( this, "speed" );
|
||||
m_turningRadius.associate( this, "turningRadius" );
|
||||
|
||||
m_bound_circle = NULL;
|
||||
m_bound_box = NULL;
|
||||
if( copy.m_bound_circle )
|
||||
m_bound_circle = new CBoundingCircle( 0.0f, 0.0f, copy.m_bound_circle );
|
||||
if( copy.m_bound_box )
|
||||
m_bound_box = new CBoundingBox( 0.0f, 0.0f, 0.0f, copy.m_bound_box );
|
||||
}
|
||||
|
||||
CBaseEntity::~CBaseEntity()
|
||||
@ -95,8 +90,6 @@ bool CBaseEntity::loadXML( CStr filename )
|
||||
DOMNode *value_node= child_element->getChildNodes()->item(0);
|
||||
CStr element_value=value_node ? XMLString::transcode(value_node->getNodeValue()) : "";
|
||||
|
||||
//m_properties[element_name] = element_value;
|
||||
|
||||
if( element_name == CStr( "Name" ) )
|
||||
{
|
||||
m_name = element_value;
|
||||
|
@ -24,32 +24,25 @@
|
||||
#include "EntityProperties.h"
|
||||
#include "BoundingObjects.h"
|
||||
|
||||
class CBaseEntity
|
||||
class CBaseEntity : public IPropertyOwner
|
||||
{
|
||||
public:
|
||||
CBaseEntity() { m_bound_circle = NULL; m_bound_box = NULL; }
|
||||
CBaseEntity( const CBaseEntity& copy );
|
||||
CBaseEntity();
|
||||
~CBaseEntity();
|
||||
// Load from XML
|
||||
bool loadXML( CStr filename );
|
||||
|
||||
// Base stats
|
||||
|
||||
|
||||
CObjectEntry* m_actorObject;
|
||||
|
||||
CStr m_name;
|
||||
CProperty_CStr m_name;
|
||||
CBoundingCircle* m_bound_circle;
|
||||
CBoundingBox* m_bound_box;
|
||||
CBoundingObject::EBoundingType m_bound_type;
|
||||
|
||||
float m_speed;
|
||||
float m_turningRadius;
|
||||
|
||||
|
||||
// Extended properties table
|
||||
|
||||
STL_HASH_MAP<CStr,CGenericProperty,CStr_hash_compare> m_properties;
|
||||
CProperty_float m_speed;
|
||||
CProperty_float m_turningRadius;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -18,8 +18,8 @@ void CBaseEntityCollection::loadTemplates()
|
||||
{
|
||||
while (vfs_next_dirent(handle, &dent, ".xml") == 0)
|
||||
{
|
||||
CBaseEntity newTemplate;
|
||||
if( newTemplate.loadXML( pathname + dent.name ) )
|
||||
CBaseEntity* newTemplate = new CBaseEntity();
|
||||
if( newTemplate->loadXML( pathname + dent.name ) )
|
||||
{
|
||||
addTemplate( newTemplate );
|
||||
LOG(NORMAL, "CBaseEntityCollection::loadTemplates(): Loaded template \"%s%s\"", pathname.c_str(), dent.name);
|
||||
@ -35,13 +35,9 @@ void CBaseEntityCollection::loadTemplates()
|
||||
LOG(ERROR, "CBaseEntityCollection::loadTemplates(): Failed to enumerate entity template directory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// He's so annoyingly slow...
|
||||
CBaseEntity* dude = getTemplate( "Prometheus Dude" );
|
||||
dude->m_speed *= 10.0f;
|
||||
}
|
||||
|
||||
void CBaseEntityCollection::addTemplate( CBaseEntity& temp )
|
||||
void CBaseEntityCollection::addTemplate( CBaseEntity* temp )
|
||||
{
|
||||
m_templates.push_back( temp );
|
||||
}
|
||||
@ -49,7 +45,7 @@ void CBaseEntityCollection::addTemplate( CBaseEntity& temp )
|
||||
CBaseEntity* CBaseEntityCollection::getTemplate( CStr name )
|
||||
{
|
||||
for( u16 t = 0; t < m_templates.size(); t++ )
|
||||
if( m_templates[t].m_name == name ) return( &( m_templates[t] ) );
|
||||
if( m_templates[t]->m_name == name ) return( m_templates[t] );
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
@ -57,7 +53,13 @@ CBaseEntity* CBaseEntityCollection::getTemplate( CStr name )
|
||||
CBaseEntity* CBaseEntityCollection::getTemplateByActor( CObjectEntry* actor )
|
||||
{
|
||||
for( u16 t = 0; t < m_templates.size(); t++ )
|
||||
if( m_templates[t].m_actorObject == actor ) return( &( m_templates[t] ) );
|
||||
if( m_templates[t]->m_actorObject == actor ) return( m_templates[t] );
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
CBaseEntityCollection::~CBaseEntityCollection()
|
||||
{
|
||||
for( u16 t = 0; t < m_templates.size(); t++ )
|
||||
delete( m_templates[t] );
|
||||
}
|
||||
|
@ -28,11 +28,12 @@
|
||||
|
||||
class CBaseEntityCollection : public Singleton<CBaseEntityCollection>
|
||||
{
|
||||
std::vector<CBaseEntity> m_templates;
|
||||
std::vector<CBaseEntity*> m_templates;
|
||||
public:
|
||||
~CBaseEntityCollection();
|
||||
CBaseEntity* getTemplate( CStr entityType );
|
||||
void loadTemplates();
|
||||
void addTemplate( CBaseEntity& temp );
|
||||
void addTemplate( CBaseEntity* temp );
|
||||
CBaseEntity* getTemplateByActor( CObjectEntry* actor );
|
||||
};
|
||||
|
||||
|
@ -11,31 +11,72 @@
|
||||
#include "Terrain.h"
|
||||
|
||||
#include "Collision.h"
|
||||
#include "PathfindEngine.h"
|
||||
|
||||
CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation )
|
||||
{
|
||||
m_position = position;
|
||||
m_orientation = orientation;
|
||||
|
||||
m_ahead.x = sin( m_orientation );
|
||||
m_ahead.y = cos( m_orientation );
|
||||
|
||||
m_base.associate( this, "template", ( void( IPropertyOwner::* )() )&CEntity::loadBase );
|
||||
m_name.associate( this, "name" );
|
||||
m_speed.associate( this, "speed" );
|
||||
m_turningRadius.associate( this, "turningRadius" );
|
||||
m_position.associate( this, "position", ( void( IPropertyOwner::* )() )&CEntity::teleport );
|
||||
m_orientation.associate( this, "orientation", ( void( IPropertyOwner::* )() )&CEntity::reorient );
|
||||
|
||||
// Set our parent unit and build us an actor.
|
||||
m_actor = NULL;
|
||||
m_bounds = NULL;
|
||||
|
||||
m_base = base;
|
||||
|
||||
loadBase();
|
||||
|
||||
snapToGround();
|
||||
updateActorTransforms();
|
||||
|
||||
}
|
||||
|
||||
CEntity::~CEntity()
|
||||
{
|
||||
for( i32 i = 0; i < m_base->m_inheritors.size(); i++ )
|
||||
if( m_base->m_inheritors[i] == this )
|
||||
m_base->m_inheritors.erase( m_base->m_inheritors.begin() + i );
|
||||
|
||||
if( m_actor )
|
||||
{
|
||||
g_UnitMan.RemoveUnit( m_actor );
|
||||
delete( m_actor );
|
||||
}
|
||||
if( m_bounds ) delete( m_bounds );
|
||||
}
|
||||
|
||||
void CEntity::loadBase()
|
||||
{
|
||||
if( m_actor )
|
||||
{
|
||||
g_UnitMan.RemoveUnit( m_actor );
|
||||
delete( m_actor );
|
||||
}
|
||||
if( m_bounds )
|
||||
{
|
||||
delete( m_bounds );
|
||||
}
|
||||
|
||||
m_actor = new CUnit(m_base->m_actorObject,m_base->m_actorObject->m_Model->Clone());
|
||||
|
||||
|
||||
// HACK: Debugging
|
||||
// assert( m_base->m_name != CStr( "Waypoint" ) );
|
||||
|
||||
// Register the actor with the renderer.
|
||||
|
||||
g_UnitMan.AddUnit( m_actor );
|
||||
|
||||
// Set up our instance data
|
||||
|
||||
m_speed = m_base->m_speed;
|
||||
m_turningRadius = m_base->m_turningRadius;
|
||||
m_position = position;
|
||||
m_orientation = orientation;
|
||||
|
||||
m_ahead.x = sin( orientation );
|
||||
m_ahead.y = cos( orientation );
|
||||
m_base->m_inheritors.push_back( this );
|
||||
rebuild();
|
||||
|
||||
if( m_base->m_bound_type == CBoundingObject::BOUND_CIRCLE )
|
||||
{
|
||||
@ -45,26 +86,6 @@ CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation )
|
||||
{
|
||||
m_bounds = new CBoundingBox( m_position.X, m_position.Z, m_ahead, m_base->m_bound_box );
|
||||
}
|
||||
|
||||
snapToGround();
|
||||
updateActorTransforms();
|
||||
|
||||
// Register the addresses of our native properties with the properties table
|
||||
|
||||
m_properties["speed"].associate( &m_speed );
|
||||
m_properties["orientation"].associate( &m_orientation );
|
||||
m_properties["position"].associate( &m_position );
|
||||
|
||||
}
|
||||
|
||||
CEntity::~CEntity()
|
||||
{
|
||||
if( m_actor )
|
||||
{
|
||||
g_UnitMan.RemoveUnit( m_actor );
|
||||
delete( m_actor );
|
||||
}
|
||||
if( m_bounds ) delete( m_bounds );
|
||||
}
|
||||
|
||||
bool isWaypoint( CEntity* e )
|
||||
@ -105,6 +126,8 @@ float CEntity::getExactGroundLevel( float x, float y )
|
||||
u16* heightmap = g_Terrain.GetHeightMap();
|
||||
unsigned long mapsize = g_Terrain.GetVerticesPerSide();
|
||||
|
||||
assert( ( xi >= 0 ) && ( xi < mapsize ) && ( yi >= 0 ) && ( yi < mapsize ) );
|
||||
|
||||
float h00 = heightmap[yi*mapsize + xi];
|
||||
float h01 = heightmap[yi*mapsize + xi + mapsize];
|
||||
float h10 = heightmap[yi*mapsize + xi + 1];
|
||||
@ -204,6 +227,39 @@ void CEntity::pushOrder( CEntityOrder& order )
|
||||
m_orderQueue.push_back( order );
|
||||
}
|
||||
|
||||
void CEntity::repath()
|
||||
{
|
||||
CVector2D destination;
|
||||
if( m_orderQueue.empty() ) return;
|
||||
|
||||
while( !m_orderQueue.empty() &&
|
||||
( ( m_orderQueue.front().m_type == CEntityOrder::ORDER_GOTO_COLLISION )
|
||||
|| ( m_orderQueue.front().m_type == CEntityOrder::ORDER_GOTO_NOPATHING )
|
||||
|| ( m_orderQueue.front().m_type == CEntityOrder::ORDER_GOTO_SMOOTHED ) ) )
|
||||
{
|
||||
destination = m_orderQueue.front().m_data[0].location;
|
||||
m_orderQueue.pop_front();
|
||||
}
|
||||
g_Pathfinder.requestPath( me, destination );
|
||||
}
|
||||
|
||||
void CEntity::reorient()
|
||||
{
|
||||
m_ahead.x = sin( m_orientation );
|
||||
m_ahead.y = cos( m_orientation );
|
||||
if( m_bounds->m_type == CBoundingObject::BOUND_OABB )
|
||||
((CBoundingBox*)m_bounds)->setOrientation( m_ahead );
|
||||
updateActorTransforms();
|
||||
}
|
||||
|
||||
void CEntity::teleport()
|
||||
{
|
||||
snapToGround();
|
||||
updateActorTransforms();
|
||||
m_bounds->setPosition( m_position.X, m_position.Z );
|
||||
repath();
|
||||
}
|
||||
|
||||
void CEntity::render()
|
||||
{
|
||||
// Rich! Help! ;)
|
||||
|
@ -47,29 +47,23 @@
|
||||
|
||||
class CEntityManager;
|
||||
|
||||
class CEntity
|
||||
class CEntity : public IPropertyOwner
|
||||
{
|
||||
friend class CEntityManager;
|
||||
private:
|
||||
// Intrinsic properties
|
||||
public:
|
||||
CStr m_name;
|
||||
float m_speed;
|
||||
float m_turningRadius;
|
||||
CVector3D m_position;
|
||||
// Intrinsic properties
|
||||
CProperty_CStr m_name;
|
||||
CProperty_float m_speed;
|
||||
CProperty_float m_turningRadius;
|
||||
CProperty_CVector3D m_position;
|
||||
CBoundingObject* m_bounds;
|
||||
float m_targetorientation;
|
||||
CVector2D m_ahead;
|
||||
float m_orientation;
|
||||
CBaseEntity* m_base;
|
||||
CProperty_float m_orientation;
|
||||
CUnit* m_actor;
|
||||
|
||||
std::deque<CEntityOrder> m_orderQueue;
|
||||
|
||||
// Extended properties table
|
||||
|
||||
STL_HASH_MAP<CStr,CGenericProperty,CStr_hash_compare> m_properties;
|
||||
|
||||
private:
|
||||
CEntity( CBaseEntity* base, CVector3D position, float orientation );
|
||||
|
||||
@ -88,6 +82,12 @@ public:
|
||||
void render();
|
||||
float getExactGroundLevel( float x, float y );
|
||||
void snapToGround();
|
||||
void repath();
|
||||
|
||||
void loadBase();
|
||||
void reorient();
|
||||
void teleport(); // Fixes things if the position is changed by something externally.
|
||||
|
||||
void pushOrder( CEntityOrder& order );
|
||||
};
|
||||
|
||||
|
@ -34,6 +34,12 @@ HEntity CEntityManager::create( CStr templatename, CVector3D position, float ori
|
||||
return( create( templateobj, position, orientation ) );
|
||||
}
|
||||
|
||||
HEntity* CEntityManager::getByHandle( u16 index )
|
||||
{
|
||||
if( index >= MAX_HANDLES ) return( NULL );
|
||||
if( !m_entities[index].m_refcount ) return( NULL );
|
||||
return( new HEntity( index ) );
|
||||
}
|
||||
std::vector<HEntity>* CEntityManager::matches( EntityPredicate predicate )
|
||||
{
|
||||
std::vector<HEntity>* matchlist = new std::vector<HEntity>;
|
||||
|
@ -42,10 +42,11 @@ public:
|
||||
~CEntityManager();
|
||||
HEntity create( CBaseEntity* base, CVector3D position, float orientation );
|
||||
HEntity create( CStr templatename, CVector3D position, float orientation );
|
||||
HEntity* getByHandle( u16 index );
|
||||
void kill( HEntity ent );
|
||||
void updateAll( float timestep );
|
||||
void dispatchAll( CMessage* msg );
|
||||
void renderAll(); // TODO MT: What's the correct way to hook this up to the renderer?
|
||||
void renderAll();
|
||||
std::vector<HEntity>* matches( EntityPredicate predicate );
|
||||
std::vector<HEntity>* getActive();
|
||||
static inline bool extant() // True if the singleton is actively maintaining handles. When false, system is shutting down, handles are quietly dumped.
|
||||
|
@ -1,621 +1,368 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "EntityProperties.h"
|
||||
#include "BaseEntityCollection.h"
|
||||
#include "scripting/JSInterface_BaseEntity.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
CGenericProperty::CGenericProperty()
|
||||
void CProperty::associate( IPropertyOwner* owner, const CStr& name )
|
||||
{
|
||||
m_type = PROP_INTEGER;
|
||||
m_integer = 0;
|
||||
m_owner = owner;
|
||||
owner->m_properties[name] = this;
|
||||
m_updateFn = NULL;
|
||||
}
|
||||
|
||||
CGenericProperty::~CGenericProperty()
|
||||
void CProperty::associate( IPropertyOwner* owner, const CStr& name, void (IPropertyOwner::*updateFn)() )
|
||||
{
|
||||
releaseData();
|
||||
m_owner = owner;
|
||||
owner->m_properties[name] = this;
|
||||
m_updateFn = updateFn;
|
||||
}
|
||||
|
||||
void CGenericProperty::releaseData()
|
||||
CProperty& CProperty::operator=( jsval value )
|
||||
{
|
||||
switch( m_type & ~PROP_TYPELOCKED )
|
||||
{
|
||||
case PROP_STRING:
|
||||
delete( m_string ); break;
|
||||
case PROP_VECTOR:
|
||||
delete( m_vector ); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CGenericProperty::operator i32()
|
||||
{
|
||||
return( toInteger() );
|
||||
}
|
||||
|
||||
CGenericProperty::operator float()
|
||||
{
|
||||
return( toFloat() );
|
||||
}
|
||||
|
||||
CGenericProperty::operator CStr()
|
||||
{
|
||||
return( toString() );
|
||||
}
|
||||
|
||||
CGenericProperty::operator CVector3D()
|
||||
{
|
||||
return( toVector() );
|
||||
}
|
||||
|
||||
CGenericProperty::operator void *()
|
||||
{
|
||||
return( toVoid() );
|
||||
}
|
||||
|
||||
CGenericProperty& CGenericProperty::operator=( int32_t value )
|
||||
{
|
||||
if( m_type & PROP_TYPELOCKED )
|
||||
{
|
||||
fromInteger( value );
|
||||
}
|
||||
else
|
||||
{
|
||||
releaseData();
|
||||
m_type = PROP_INTEGER;
|
||||
m_integer = value;
|
||||
}
|
||||
set( value );
|
||||
return( *this );
|
||||
}
|
||||
|
||||
CGenericProperty& CGenericProperty::operator=( float value )
|
||||
CProperty_i32::CProperty_i32()
|
||||
{
|
||||
if( m_type & PROP_TYPELOCKED )
|
||||
{
|
||||
fromFloat( value );
|
||||
}
|
||||
else
|
||||
{
|
||||
releaseData();
|
||||
m_type = PROP_FLOAT;
|
||||
m_float = value;
|
||||
}
|
||||
modifier = NULL;
|
||||
}
|
||||
|
||||
CProperty_i32::~CProperty_i32()
|
||||
{
|
||||
if( modifier )
|
||||
delete( modifier );
|
||||
}
|
||||
|
||||
inline CProperty_i32& CProperty_i32::operator =( i32 value )
|
||||
{
|
||||
if( !modifier )
|
||||
modifier = new SProperty_NumericModifier();
|
||||
*modifier = (float)value;
|
||||
data = value;
|
||||
return( *this );
|
||||
}
|
||||
|
||||
CGenericProperty& CGenericProperty::operator=( CStr& value )
|
||||
void CProperty_i32::set( jsval value )
|
||||
{
|
||||
if( m_type & PROP_TYPELOCKED )
|
||||
if( !modifier )
|
||||
modifier = new SProperty_NumericModifier();
|
||||
try
|
||||
{
|
||||
fromString( value );
|
||||
*modifier = (float)g_ScriptingHost.ValueToInt( value );
|
||||
}
|
||||
else
|
||||
catch( ... )
|
||||
{
|
||||
releaseData();
|
||||
m_type = PROP_STRING;
|
||||
m_string = new CStr( value );
|
||||
*modifier = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CProperty_i32::rebuild( CProperty* parent, bool triggerFn )
|
||||
{
|
||||
CProperty_i32* _parent = (CProperty_i32*)parent;
|
||||
i32 newvalue = 0;
|
||||
if( _parent )
|
||||
newvalue = *_parent;
|
||||
if( modifier )
|
||||
{
|
||||
newvalue *= modifier->multiplicative;
|
||||
newvalue += modifier->additive;
|
||||
}
|
||||
if( data == newvalue )
|
||||
return( false ); // No change.
|
||||
data = newvalue;
|
||||
if( triggerFn && m_updateFn ) (m_owner->*m_updateFn)();
|
||||
return( true );
|
||||
}
|
||||
|
||||
inline CProperty_i32::operator i32()
|
||||
{
|
||||
return( data );
|
||||
}
|
||||
|
||||
CProperty_i32::operator jsval()
|
||||
{
|
||||
return( INT_TO_JSVAL( data ) );
|
||||
}
|
||||
|
||||
CProperty_float::CProperty_float()
|
||||
{
|
||||
modifier = NULL;
|
||||
}
|
||||
|
||||
CProperty_float::~CProperty_float()
|
||||
{
|
||||
if( modifier )
|
||||
modifier = NULL;
|
||||
}
|
||||
|
||||
CProperty_float& CProperty_float::operator =( const float& value )
|
||||
{
|
||||
if( !modifier )
|
||||
modifier = new SProperty_NumericModifier();
|
||||
*modifier = value;
|
||||
data = value;
|
||||
return( *this );
|
||||
}
|
||||
|
||||
CGenericProperty& CGenericProperty::operator=( CVector3D& value )
|
||||
void CProperty_float::set( const jsval value )
|
||||
{
|
||||
if( m_type & PROP_TYPELOCKED )
|
||||
if( !modifier )
|
||||
modifier = new SProperty_NumericModifier();
|
||||
try
|
||||
{
|
||||
fromVector( value );
|
||||
*modifier = (float)g_ScriptingHost.ValueToDouble( value );
|
||||
}
|
||||
else
|
||||
catch( ... )
|
||||
{
|
||||
releaseData();
|
||||
m_type = PROP_VECTOR;
|
||||
m_vector = new CVector3D( value );
|
||||
*modifier = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
bool CProperty_float::rebuild( CProperty* parent, bool triggerFn )
|
||||
{
|
||||
CProperty_float* _parent = (CProperty_float*)parent;
|
||||
float newvalue = 0;
|
||||
if( _parent )
|
||||
newvalue = *_parent;
|
||||
if( modifier )
|
||||
{
|
||||
newvalue *= modifier->multiplicative;
|
||||
newvalue += modifier->additive;
|
||||
}
|
||||
if( data == newvalue )
|
||||
return( false ); // No change.
|
||||
data = newvalue;
|
||||
if( triggerFn && m_updateFn ) (m_owner->*m_updateFn)();
|
||||
return( true );
|
||||
}
|
||||
|
||||
CProperty_float::operator float()
|
||||
{
|
||||
return( data );
|
||||
}
|
||||
|
||||
CProperty_float::operator jsval()
|
||||
{
|
||||
return( DOUBLE_TO_JSVAL( JS_NewDouble( g_ScriptingHost.getContext(), (jsdouble)data ) ) );
|
||||
}
|
||||
|
||||
CProperty_float::operator bool()
|
||||
{
|
||||
return( data );
|
||||
}
|
||||
|
||||
float CProperty_float::operator+( float value )
|
||||
{
|
||||
return( data + value );
|
||||
}
|
||||
|
||||
float CProperty_float::operator-( float value )
|
||||
{
|
||||
return( data - value );
|
||||
}
|
||||
|
||||
float CProperty_float::operator*( float value )
|
||||
{
|
||||
return( data * value );
|
||||
}
|
||||
|
||||
float CProperty_float::operator/( float value )
|
||||
{
|
||||
return( data / value );
|
||||
}
|
||||
|
||||
bool CProperty_float::operator<( float value )
|
||||
{
|
||||
return( data < value );
|
||||
}
|
||||
|
||||
bool CProperty_float::operator>( float value )
|
||||
{
|
||||
return( data > value );
|
||||
}
|
||||
|
||||
bool CProperty_float::operator==( float value )
|
||||
{
|
||||
return( data == value );
|
||||
}
|
||||
|
||||
CProperty_CStr::CProperty_CStr()
|
||||
{
|
||||
modifier = NULL;
|
||||
}
|
||||
|
||||
CProperty_CStr::~CProperty_CStr()
|
||||
{
|
||||
if( modifier )
|
||||
delete( modifier );
|
||||
}
|
||||
|
||||
CProperty_CStr& CProperty_CStr::operator=( const CStr& value )
|
||||
{
|
||||
if( !modifier )
|
||||
modifier = new SProperty_StringModifier();
|
||||
*modifier = value;
|
||||
m_String = value;
|
||||
return( *this );
|
||||
}
|
||||
|
||||
CGenericProperty& CGenericProperty::operator =( void* value )
|
||||
void CProperty_CStr::set( jsval value )
|
||||
{
|
||||
if( m_type & PROP_TYPELOCKED )
|
||||
if( !modifier )
|
||||
modifier = new SProperty_StringModifier();
|
||||
try
|
||||
{
|
||||
fromVoid( value );
|
||||
*modifier = g_ScriptingHost.ValueToString( value );
|
||||
}
|
||||
else
|
||||
catch( ... )
|
||||
{
|
||||
releaseData();
|
||||
m_type = PROP_PTR;
|
||||
m_ptr = value;
|
||||
*modifier = CStr();
|
||||
m_String.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool CProperty_CStr::rebuild( CProperty* parent, bool triggerFn )
|
||||
{
|
||||
CProperty_CStr* _parent = (CProperty_CStr*)parent;
|
||||
CStr newvalue = "";
|
||||
if( _parent )
|
||||
newvalue = *_parent;
|
||||
if( modifier )
|
||||
newvalue = modifier->replacement;
|
||||
|
||||
if( *this == newvalue )
|
||||
return( false ); // No change.
|
||||
m_String = newvalue;
|
||||
if( triggerFn && m_updateFn ) (m_owner->*m_updateFn)();
|
||||
return( true );
|
||||
}
|
||||
|
||||
CProperty_CStr::operator jsval()
|
||||
{
|
||||
return( STRING_TO_JSVAL( JS_NewStringCopyZ( g_ScriptingHost.getContext(), m_String.c_str() ) ) );
|
||||
}
|
||||
|
||||
CProperty_CVector3D& CProperty_CVector3D::operator =( const CVector3D& value )
|
||||
{
|
||||
*( (CVector3D*)this ) = value;
|
||||
return( *this );
|
||||
}
|
||||
|
||||
void CGenericProperty::associate( i32* value )
|
||||
void CProperty_CVector3D::set( jsval value )
|
||||
{
|
||||
i32 current = toInteger();
|
||||
releaseData();
|
||||
m_type = (EPropTypes)( PROP_INTEGER | PROP_INTRINSIC | PROP_TYPELOCKED );
|
||||
m_integerptr = value;
|
||||
//*m_integerptr = current;
|
||||
}
|
||||
|
||||
void CGenericProperty::associate( float* value )
|
||||
{
|
||||
float current = toFloat();
|
||||
releaseData();
|
||||
m_type = (EPropTypes)( PROP_FLOAT | PROP_INTRINSIC | PROP_TYPELOCKED );
|
||||
m_floatptr = value;
|
||||
//*m_floatptr = current;
|
||||
}
|
||||
|
||||
void CGenericProperty::associate( CStr* value )
|
||||
{
|
||||
CStr current = toString();
|
||||
releaseData();
|
||||
m_type = (EPropTypes)( PROP_STRING | PROP_VECTOR | PROP_TYPELOCKED );
|
||||
m_string = value;
|
||||
//*m_string = current;
|
||||
}
|
||||
|
||||
void CGenericProperty::associate( CVector3D* value )
|
||||
{
|
||||
CVector3D current = toVector();
|
||||
releaseData();
|
||||
m_type = (EPropTypes)( PROP_VECTOR | PROP_INTRINSIC | PROP_TYPELOCKED );
|
||||
m_vector = value;
|
||||
//*value = current;
|
||||
}
|
||||
|
||||
void CGenericProperty::typelock( EPropTypes type )
|
||||
{
|
||||
if( m_type & PROP_INTRINSIC ) return;
|
||||
switch( type )
|
||||
JSObject* vector3d = JSVAL_TO_OBJECT( value );
|
||||
if( !JSVAL_IS_OBJECT( value ) || ( JS_GetClass( vector3d ) != &JSI_Vector3D::JSI_class ) )
|
||||
{
|
||||
case PROP_INTEGER:
|
||||
X = 0.0f; Y = 0.0f; Z = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
CVector3D* copy = ( (JSI_Vector3D::Vector3D_Info*)JS_GetPrivate( g_ScriptingHost.getContext(), vector3d ) )->vector;
|
||||
X = copy->X;
|
||||
Y = copy->Y;
|
||||
Z = copy->Z;
|
||||
}
|
||||
}
|
||||
|
||||
bool CProperty_CVector3D::rebuild( CProperty* parent, bool triggerFn )
|
||||
{
|
||||
if( triggerFn && m_updateFn ) (m_owner->*m_updateFn)();
|
||||
return( false ); // Vector properties aren't inheritable.
|
||||
}
|
||||
|
||||
CProperty_CVector3D::operator jsval()
|
||||
{
|
||||
JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );
|
||||
JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( this, m_owner, m_updateFn ) );
|
||||
return( OBJECT_TO_JSVAL( vector3d ) );
|
||||
}
|
||||
|
||||
CProperty_CBaseEntityPtr& CProperty_CBaseEntityPtr::operator =( CBaseEntity* value )
|
||||
{
|
||||
data = value;
|
||||
return( *this );
|
||||
}
|
||||
|
||||
void CProperty_CBaseEntityPtr::set( jsval value )
|
||||
{
|
||||
JSObject* baseEntity = JSVAL_TO_OBJECT( value );
|
||||
if( JSVAL_IS_OBJECT( value ) && ( JS_GetClass( baseEntity ) == &JSI_BaseEntity::JSI_class ) )
|
||||
data = (CBaseEntity*)JS_GetPrivate( g_ScriptingHost.getContext(), baseEntity );
|
||||
}
|
||||
|
||||
bool CProperty_CBaseEntityPtr::rebuild( CProperty* parent, bool triggerFn )
|
||||
{
|
||||
if( triggerFn && m_updateFn ) (m_owner->*m_updateFn)();
|
||||
return( false ); // CBaseEntity* properties aren't inheritable.
|
||||
}
|
||||
|
||||
CProperty_CBaseEntityPtr::operator jsval()
|
||||
{
|
||||
JSObject* baseEntity = JS_NewObject( g_ScriptingHost.getContext(), &JSI_BaseEntity::JSI_class, NULL, NULL );
|
||||
JS_SetPrivate( g_ScriptingHost.getContext(), baseEntity, data );
|
||||
return( OBJECT_TO_JSVAL( baseEntity ) );
|
||||
}
|
||||
|
||||
CProperty_CBaseEntityPtr::operator bool()
|
||||
{
|
||||
return( data != NULL );
|
||||
}
|
||||
|
||||
CProperty_CBaseEntityPtr::operator CBaseEntity*()
|
||||
{
|
||||
return( data );
|
||||
}
|
||||
|
||||
CBaseEntity& CProperty_CBaseEntityPtr::operator *() const
|
||||
{
|
||||
return( *data );
|
||||
}
|
||||
|
||||
CBaseEntity* CProperty_CBaseEntityPtr::operator ->() const
|
||||
{
|
||||
return( data );
|
||||
}
|
||||
|
||||
void IPropertyOwner::rebuild( CStr propertyName )
|
||||
{
|
||||
CProperty* thisProperty = m_properties[propertyName];
|
||||
CProperty* baseProperty = NULL;
|
||||
if( m_base )
|
||||
{
|
||||
if( m_base->m_properties.find( propertyName ) != m_base->m_properties.end() )
|
||||
baseProperty = m_base->m_properties[propertyName];
|
||||
}
|
||||
if( thisProperty->rebuild( baseProperty ) )
|
||||
{
|
||||
std::vector<IPropertyOwner*>::iterator it;
|
||||
for( it = m_inheritors.begin(); it != m_inheritors.end(); it++ )
|
||||
(*it)->rebuild( propertyName );
|
||||
}
|
||||
}
|
||||
|
||||
void IPropertyOwner::rebuild()
|
||||
{
|
||||
STL_HASH_MAP<CStr,CProperty*,CStr_hash_compare>::iterator property;
|
||||
if( m_base )
|
||||
{
|
||||
for( property = m_properties.begin(); property != m_properties.end(); property++ )
|
||||
{
|
||||
i32 current = toInteger();
|
||||
releaseData();
|
||||
m_integer = current;
|
||||
CProperty* baseProperty = NULL;
|
||||
if( m_base->m_properties.find( property->first ) != m_base->m_properties.end() )
|
||||
baseProperty = m_base->m_properties[property->first];
|
||||
(property->second)->rebuild( baseProperty, false );
|
||||
}
|
||||
break;
|
||||
case PROP_FLOAT:
|
||||
{
|
||||
float current = toFloat();
|
||||
releaseData();
|
||||
m_float = current;
|
||||
}
|
||||
break;
|
||||
case PROP_STRING:
|
||||
{
|
||||
CStr* current = new CStr( toString() );
|
||||
releaseData();
|
||||
m_string = current;
|
||||
}
|
||||
break;
|
||||
case PROP_VECTOR:
|
||||
{
|
||||
CVector3D* current = new CVector3D( toVector() );
|
||||
releaseData();
|
||||
m_vector = current;
|
||||
}
|
||||
break;
|
||||
case PROP_PTR:
|
||||
{
|
||||
void* current = toVoid();
|
||||
releaseData();
|
||||
m_ptr = current;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
m_type = (EPropTypes)( type | PROP_TYPELOCKED );
|
||||
}
|
||||
|
||||
void CGenericProperty::typeloose()
|
||||
{
|
||||
if( m_type & PROP_INTRINSIC ) return;
|
||||
m_type = (EPropTypes)( m_type & ~PROP_TYPELOCKED );
|
||||
}
|
||||
|
||||
i32& CGenericProperty::asInteger()
|
||||
{
|
||||
assert( ( m_type & PROP_STRIPFLAGS ) == PROP_INTEGER );
|
||||
if( m_type & PROP_INTRINSIC )
|
||||
return( *m_integerptr );
|
||||
return( m_integer );
|
||||
}
|
||||
|
||||
float& CGenericProperty::asFloat()
|
||||
{
|
||||
assert( ( m_type & PROP_STRIPFLAGS ) == PROP_FLOAT );
|
||||
if( m_type & PROP_INTRINSIC )
|
||||
return( *m_floatptr );
|
||||
return( m_float );
|
||||
}
|
||||
|
||||
CStr& CGenericProperty::asString()
|
||||
{
|
||||
assert( ( m_type & PROP_STRIPFLAGS ) == PROP_STRING );
|
||||
return( *m_string );
|
||||
}
|
||||
|
||||
CVector3D& CGenericProperty::asVector()
|
||||
{
|
||||
assert( ( m_type & PROP_STRIPFLAGS ) == PROP_VECTOR );
|
||||
return( *m_vector );
|
||||
}
|
||||
|
||||
i32 CGenericProperty::toInteger()
|
||||
{
|
||||
switch( m_type & PROP_STRIPFLAGS )
|
||||
else
|
||||
{
|
||||
case PROP_INTEGER:
|
||||
return( asInteger() );
|
||||
case PROP_FLOAT:
|
||||
return( (i32)asFloat() );
|
||||
case PROP_STRING:
|
||||
case PROP_STRING_INTRINSIC:
|
||||
return( (i32)( asString().ToInt() ) );
|
||||
case PROP_VECTOR:
|
||||
case PROP_VECTOR_INTRINSIC:
|
||||
case PROP_PTR:
|
||||
return( 0 );
|
||||
default:
|
||||
assert( 0 && "Invalid property type" );
|
||||
for( property = m_properties.begin(); property != m_properties.end(); property++ )
|
||||
(property->second)->rebuild( NULL, false );
|
||||
}
|
||||
return( 0 );
|
||||
|
||||
std::vector<IPropertyOwner*>::iterator it;
|
||||
for( it = m_inheritors.begin(); it != m_inheritors.end(); it++ )
|
||||
(*it)->rebuild();
|
||||
|
||||
}
|
||||
|
||||
float CGenericProperty::toFloat()
|
||||
{
|
||||
switch( m_type & PROP_STRIPFLAGS )
|
||||
{
|
||||
case PROP_INTEGER:
|
||||
return( (float)asInteger() );
|
||||
case PROP_FLOAT:
|
||||
return( asFloat() );
|
||||
case PROP_STRING:
|
||||
case PROP_STRING_INTRINSIC:
|
||||
return( asString().ToFloat() );
|
||||
case PROP_VECTOR:
|
||||
case PROP_VECTOR_INTRINSIC:
|
||||
case PROP_PTR:
|
||||
return( 0.0f );
|
||||
default:
|
||||
assert( 0 && "Invalid property type" );
|
||||
}
|
||||
return( 0.0f );
|
||||
}
|
||||
|
||||
CStr CGenericProperty::toString()
|
||||
{
|
||||
switch( m_type & PROP_STRIPFLAGS )
|
||||
{
|
||||
case PROP_INTEGER:
|
||||
return( CStr( asInteger() ) );
|
||||
case PROP_FLOAT:
|
||||
return( CStr( asFloat() ) );
|
||||
case PROP_STRING:
|
||||
return( CStr( asString() ) );
|
||||
case PROP_VECTOR:
|
||||
{
|
||||
char buffer[256];
|
||||
snprintf( buffer, 250, "{ %f, %f, %f }", asVector().X, asVector().Y, asVector().Z );
|
||||
return( CStr( buffer ) );
|
||||
}
|
||||
case PROP_PTR:
|
||||
return CStr();
|
||||
default:
|
||||
assert( 0 && "Invalid property type" );
|
||||
}
|
||||
return CStr();
|
||||
}
|
||||
|
||||
CVector3D CGenericProperty::toVector()
|
||||
{
|
||||
switch( m_type & PROP_STRIPFLAGS )
|
||||
{
|
||||
case PROP_VECTOR:
|
||||
return( CVector3D( asVector() ) );
|
||||
case PROP_INTEGER:
|
||||
case PROP_FLOAT:
|
||||
case PROP_STRING:
|
||||
case PROP_PTR:
|
||||
return CVector3D();
|
||||
default:
|
||||
assert( 0 && "Invalid property type" );
|
||||
}
|
||||
return CVector3D();
|
||||
}
|
||||
|
||||
void* CGenericProperty::toVoid()
|
||||
{
|
||||
switch( m_type & PROP_STRIPFLAGS )
|
||||
{
|
||||
case PROP_PTR:
|
||||
return( m_ptr );
|
||||
case PROP_INTEGER:
|
||||
case PROP_INTEGER_INTRINSIC:
|
||||
case PROP_FLOAT:
|
||||
case PROP_FLOAT_INTRINSIC:
|
||||
case PROP_STRING:
|
||||
case PROP_STRING_INTRINSIC:
|
||||
case PROP_VECTOR:
|
||||
case PROP_VECTOR_INTRINSIC:
|
||||
return( NULL );
|
||||
default:
|
||||
assert( 0 && "Invalid property type" );
|
||||
}
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
void CGenericProperty::fromInteger( i32 value )
|
||||
{
|
||||
switch( m_type & PROP_STRIPFLAGS )
|
||||
{
|
||||
case PROP_INTEGER:
|
||||
asInteger() = value; return;
|
||||
case PROP_FLOAT:
|
||||
asFloat() = (float)value; return;
|
||||
case PROP_STRING:
|
||||
asString() = value; return;
|
||||
case PROP_VECTOR:
|
||||
asVector() = CVector3D(); return;
|
||||
case PROP_PTR:
|
||||
m_ptr = NULL; return;
|
||||
default:
|
||||
assert( 0 && "Invalid property type" );
|
||||
}
|
||||
}
|
||||
|
||||
void CGenericProperty::fromFloat( float value )
|
||||
{
|
||||
switch( m_type & PROP_STRIPFLAGS )
|
||||
{
|
||||
case PROP_INTEGER:
|
||||
asInteger() = (i32)value; return;
|
||||
case PROP_FLOAT:
|
||||
asFloat() = value; return;
|
||||
case PROP_STRING:
|
||||
asString() = value; return;
|
||||
case PROP_VECTOR:
|
||||
asVector() = CVector3D(); return;
|
||||
case PROP_PTR:
|
||||
m_ptr = NULL; return;
|
||||
default:
|
||||
assert( 0 && "Invalid property type" );
|
||||
}
|
||||
}
|
||||
|
||||
void CGenericProperty::fromString( CStr& value )
|
||||
{
|
||||
switch( m_type & PROP_STRIPFLAGS )
|
||||
{
|
||||
case PROP_INTEGER:
|
||||
asInteger() = value.ToInt(); return;
|
||||
case PROP_FLOAT:
|
||||
asFloat() = value.ToFloat(); return;
|
||||
case PROP_STRING:
|
||||
asString() = value; return;
|
||||
case PROP_VECTOR:
|
||||
asVector() = CVector3D(); return;
|
||||
case PROP_PTR:
|
||||
m_ptr = NULL; return;
|
||||
default:
|
||||
assert( 0 && "Invalid property type" );
|
||||
}
|
||||
}
|
||||
|
||||
void CGenericProperty::fromVector( CVector3D& value )
|
||||
{
|
||||
switch( m_type & PROP_STRIPFLAGS )
|
||||
{
|
||||
case PROP_INTEGER:
|
||||
asInteger() = 0; return;
|
||||
case PROP_FLOAT:
|
||||
asFloat() = 0.0f; return;
|
||||
case PROP_STRING:
|
||||
{
|
||||
char buffer[256];
|
||||
snprintf( buffer, 250, "{ %f, %f, %f }", value.X, value.Y, value.Z );
|
||||
asString() = CStr( buffer );
|
||||
}
|
||||
return;
|
||||
case PROP_VECTOR:
|
||||
asVector() = CVector3D( value ); return;
|
||||
case PROP_PTR:
|
||||
m_ptr = NULL; return;
|
||||
default:
|
||||
assert( 0 && "Invalid property type" );
|
||||
}
|
||||
}
|
||||
|
||||
void CGenericProperty::fromVoid( void* value )
|
||||
{
|
||||
switch( m_type & PROP_STRIPFLAGS )
|
||||
{
|
||||
case PROP_INTEGER:
|
||||
asInteger() = 0; return;
|
||||
case PROP_FLOAT:
|
||||
asFloat() = 0.0f; return;
|
||||
case PROP_STRING:
|
||||
asString() = CStr(); return;
|
||||
case PROP_VECTOR:
|
||||
asVector() = CVector3D(); return;
|
||||
case PROP_PTR:
|
||||
m_ptr = value; return;
|
||||
default:
|
||||
assert( 0 && "Invalid property type" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Here lies the old version of CGenericProperty. Will remove it when I know the new one works.
|
||||
|
||||
CGenericProperty::CGenericProperty()
|
||||
{
|
||||
m_type = PROP_INTEGER;
|
||||
m_integer = 0;
|
||||
}
|
||||
|
||||
CGenericProperty::CGenericProperty( i32 value )
|
||||
{
|
||||
m_type = PROP_INTEGER;
|
||||
m_integer = value;
|
||||
}
|
||||
|
||||
CGenericProperty::CGenericProperty( float value )
|
||||
{
|
||||
m_type = PROP_FLOAT;
|
||||
m_float = value;
|
||||
}
|
||||
|
||||
CGenericProperty::CGenericProperty( CStr& value )
|
||||
{
|
||||
m_type = PROP_STRING;
|
||||
m_string = new CStr( value );
|
||||
}
|
||||
|
||||
CGenericProperty::CGenericProperty( CVector3D& value )
|
||||
{
|
||||
m_type = PROP_VECTOR;
|
||||
m_vector = new CVector3D( value );
|
||||
}
|
||||
|
||||
CGenericProperty::CGenericProperty( void* value )
|
||||
{
|
||||
m_type = PROP_PTR;
|
||||
m_ptr = value;
|
||||
}
|
||||
|
||||
CGenericProperty::CGenericProperty( i32* value )
|
||||
{
|
||||
m_type = PROP_INTEGER_INTRINSIC;
|
||||
m_integerptr = value;
|
||||
}
|
||||
|
||||
CGenericProperty::CGenericProperty( float* value )
|
||||
{
|
||||
m_type = PROP_FLOAT_INTRINSIC;
|
||||
m_floatptr = value;
|
||||
}
|
||||
|
||||
CGenericProperty::CGenericProperty( CStr* value )
|
||||
{
|
||||
m_type = PROP_STRING_INTRINSIC;
|
||||
m_string = value;
|
||||
}
|
||||
|
||||
CGenericProperty::CGenericProperty( CVector3D* value )
|
||||
{
|
||||
m_type = PROP_VECTOR_INTRINSIC;
|
||||
m_vector = value;
|
||||
}
|
||||
|
||||
CGenericProperty::~CGenericProperty()
|
||||
{
|
||||
switch( m_type )
|
||||
{
|
||||
case PROP_STRING:
|
||||
delete( m_string ); break;
|
||||
case PROP_VECTOR:
|
||||
delete( m_vector ); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CGenericProperty::operator CStr&()
|
||||
{
|
||||
char working[64];
|
||||
switch( m_type )
|
||||
{
|
||||
case PROP_STRING:
|
||||
case PROP_STRING_INTRINSIC:
|
||||
return( *m_string );
|
||||
case PROP_VECTOR:
|
||||
case PROP_VECTOR_INTRINSIC:
|
||||
snprintf( working, 63, "{ %f, %f, %f }", m_vector->X, m_vector->Y, m_vector->Z );
|
||||
working[63] = 0;
|
||||
return( CStr( working ) );
|
||||
case PROP_INTEGER:
|
||||
return( CStr( m_integer ) );
|
||||
case PROP_INTEGER_INTRINSIC:
|
||||
return( CStr( *m_integerptr ) );
|
||||
case PROP_FLOAT:
|
||||
return( CStr( m_float ) );
|
||||
case PROP_FLOAT_INTRINSIC:
|
||||
return( CStr( *m_floatptr ) );
|
||||
default:
|
||||
return CStr();
|
||||
}
|
||||
}
|
||||
|
||||
CGenericProperty::operator CVector3D()
|
||||
{
|
||||
switch( m_type )
|
||||
{
|
||||
case PROP_VECTOR:
|
||||
return( *m_vector );
|
||||
default:
|
||||
return CVector3D();
|
||||
}
|
||||
}
|
||||
|
||||
CGenericProperty::operator i32()
|
||||
{
|
||||
switch( m_type )
|
||||
{
|
||||
case PROP_INTEGER:
|
||||
return( m_integer );
|
||||
case PROP_INTEGER_INTRINSIC:
|
||||
return( *m_integerptr );
|
||||
case PROP_FLOAT:
|
||||
return( (i32)m_float );
|
||||
case PROP_FLOAT_INTRINSIC:
|
||||
return( (i32)*m_floatptr );
|
||||
case PROP_STRING:
|
||||
return( m_string->ToInt() );
|
||||
default:
|
||||
return( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
CGenericProperty::operator float()
|
||||
{
|
||||
switch( m_type )
|
||||
{
|
||||
case PROP_INTEGER:
|
||||
return( (float)m_integer );
|
||||
case PROP_INTEGER_INTRINSIC:
|
||||
return( (float)*m_integerptr );
|
||||
case PROP_FLOAT:
|
||||
return( m_float );
|
||||
case PROP_FLOAT_INTRINSIC:
|
||||
return( *m_floatptr );
|
||||
case PROP_STRING:
|
||||
return( m_string->ToFloat() );
|
||||
default:
|
||||
return( 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
CGenericProperty::operator void*()
|
||||
{
|
||||
switch( m_type )
|
||||
{
|
||||
case PROP_PTR:
|
||||
return( m_ptr );
|
||||
default:
|
||||
return( NULL );
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -17,6 +17,9 @@
|
||||
|
||||
#include "CStr.h"
|
||||
#include "Vector3D.h"
|
||||
#include "scripting/ScriptingHost.h"
|
||||
#include "scripting/JSInterface_Entity.h"
|
||||
#include "scripting/JSInterface_Vector3D.h"
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
||||
@ -35,89 +38,126 @@
|
||||
|
||||
#endif
|
||||
|
||||
class CGenericProperty
|
||||
class IPropertyOwner;
|
||||
class CBaseEntity;
|
||||
class CProperty;
|
||||
struct SProperty_NumericModifier;
|
||||
struct SProperty_StringModifier;
|
||||
|
||||
class CProperty
|
||||
{
|
||||
protected:
|
||||
IPropertyOwner* m_owner;
|
||||
void (IPropertyOwner::*m_updateFn)();
|
||||
virtual void set( const jsval value ) = 0;
|
||||
public:
|
||||
CProperty& operator=( const jsval value );
|
||||
virtual operator jsval() = 0;
|
||||
virtual bool rebuild( CProperty* parent, bool triggerFn = true ) = 0; // Returns true if the rebuild changed the value of this property.
|
||||
void associate( IPropertyOwner* owner, const CStr& name );
|
||||
void associate( IPropertyOwner* owner, const CStr& name, void (IPropertyOwner::*updateFn)() );
|
||||
};
|
||||
|
||||
class CProperty_i32 : public CProperty
|
||||
{
|
||||
i32 data;
|
||||
SProperty_NumericModifier* modifier;
|
||||
public:
|
||||
CProperty_i32();
|
||||
~CProperty_i32();
|
||||
void set( const jsval value );
|
||||
operator jsval();
|
||||
bool rebuild( CProperty* parent, bool triggerFn = true );
|
||||
CProperty_i32& operator=( const i32 value );
|
||||
operator i32();
|
||||
};
|
||||
|
||||
class CProperty_float : public CProperty
|
||||
{
|
||||
float data;
|
||||
SProperty_NumericModifier* modifier;
|
||||
public:
|
||||
CProperty_float();
|
||||
~CProperty_float();
|
||||
void set( const jsval value );
|
||||
operator jsval();
|
||||
bool rebuild( CProperty* parent, bool triggerFn = true );
|
||||
CProperty_float& operator=( const float& value );
|
||||
operator float();
|
||||
operator bool();
|
||||
float operator+( float value );
|
||||
float operator-( float value );
|
||||
float operator*( float value );
|
||||
float operator/( float value );
|
||||
bool operator<( float value );
|
||||
bool operator>( float value );
|
||||
bool operator==( float value );
|
||||
};
|
||||
|
||||
class CProperty_CStr : public CProperty, public CStr
|
||||
{
|
||||
SProperty_StringModifier* modifier;
|
||||
public:
|
||||
CProperty_CStr();
|
||||
~CProperty_CStr();
|
||||
void set( const jsval value );
|
||||
operator jsval();
|
||||
bool rebuild( CProperty* parent, bool triggerFn = true );
|
||||
CProperty_CStr& operator=( const CStr& value );
|
||||
};
|
||||
|
||||
class CProperty_CVector3D : public CProperty, public CVector3D
|
||||
{
|
||||
public:
|
||||
enum EPropTypes
|
||||
{
|
||||
PROP_INTRINSIC = 256,
|
||||
PROP_TYPELOCKED = 512,
|
||||
PROP_STRIPFLAGS = 255,
|
||||
PROP_INTEGER = 0,
|
||||
PROP_FLOAT,
|
||||
PROP_STRING,
|
||||
PROP_VECTOR,
|
||||
PROP_PTR,
|
||||
PROP_INTEGER_INTRINSIC = PROP_INTEGER | PROP_INTRINSIC,
|
||||
PROP_FLOAT_INTRINSIC = PROP_FLOAT | PROP_INTRINSIC,
|
||||
PROP_STRING_INTRINSIC = PROP_STRING | PROP_INTRINSIC,
|
||||
PROP_VECTOR_INTRINSIC = PROP_VECTOR | PROP_INTRINSIC
|
||||
};
|
||||
EPropTypes m_type;
|
||||
private:
|
||||
union
|
||||
{
|
||||
i32 m_integer;
|
||||
i32* m_integerptr;
|
||||
float m_float;
|
||||
float* m_floatptr;
|
||||
CStr* m_string;
|
||||
CVector3D* m_vector;
|
||||
void* m_ptr;
|
||||
};
|
||||
void set( const jsval value );
|
||||
operator jsval();
|
||||
bool rebuild( CProperty* parent, bool triggerFn = true );
|
||||
CProperty_CVector3D& operator=( const CVector3D& value );
|
||||
};
|
||||
|
||||
class CProperty_CBaseEntityPtr : public CProperty
|
||||
{
|
||||
CBaseEntity* data;
|
||||
public:
|
||||
CGenericProperty(); // Create an integer property containing 0.
|
||||
~CGenericProperty();
|
||||
void releaseData();
|
||||
void set( const jsval value );
|
||||
operator jsval();
|
||||
bool rebuild( CProperty* parent, bool triggerFn = true );
|
||||
operator CBaseEntity*();
|
||||
operator bool();
|
||||
CBaseEntity& operator*() const;
|
||||
CBaseEntity* operator->() const;
|
||||
CProperty_CBaseEntityPtr& operator=( CBaseEntity* value );
|
||||
};
|
||||
|
||||
// Associator functions: Links the property with the specified engine variable.
|
||||
void associate( i32* value );
|
||||
void associate( float* value );
|
||||
void associate( CStr* value );
|
||||
void associate( CVector3D* value );
|
||||
// e.g. Entities and their templates.
|
||||
class IPropertyOwner
|
||||
{
|
||||
public:
|
||||
CProperty_CBaseEntityPtr m_base;
|
||||
STL_HASH_MAP<CStr,CProperty*,CStr_hash_compare> m_properties;
|
||||
std::vector<IPropertyOwner*> m_inheritors;
|
||||
void rebuild( CStr propName ); // Recursively rebuild just the named property over the inheritance tree.
|
||||
void rebuild(); // Recursively rebuild everything over the inheritance tree.
|
||||
};
|
||||
|
||||
// Getter functions: Attempts to convert the property to the given type.
|
||||
operator i32(); // Convert to an integer if possible (integer, float, some strings), otherwise returns 0.
|
||||
operator float(); // Convert to a float if possible (integer, float, some strings), otherwise returns 0.0f.
|
||||
operator CStr(); // Convert to a string if possible (all except generic pointer), otherwise returns CStr().
|
||||
operator CVector3D(); // If this property is a vector, returns that vector, otherwise returns CVector3D().
|
||||
operator void*(); // If this property is a generic pointer, returns that pointer, otherwise returns NULL.
|
||||
struct SProperty_NumericModifier
|
||||
{
|
||||
float multiplicative;
|
||||
float additive;
|
||||
void operator=( float value )
|
||||
{
|
||||
multiplicative = 0.0f;
|
||||
additive = value;
|
||||
}
|
||||
};
|
||||
|
||||
// Setter functions: If this is a typelocked property, attempts to convert the given data
|
||||
// into the appropriate type, otherwise setting the associated value to 0, 0.0f, CStr() or CVector3D().
|
||||
// If this property is typeloose, converts this property into one of the same type
|
||||
// as the given value, then stores that value in this property.
|
||||
CGenericProperty& operator=( i32 value );
|
||||
CGenericProperty& operator=( float value );
|
||||
CGenericProperty& operator=( CStr& value );
|
||||
CGenericProperty& operator=( CVector3D& value );
|
||||
CGenericProperty& operator=( void* value ); // Be careful with this one. A lot of things will cast to void*.
|
||||
// Especially pointers you meant to associate().
|
||||
|
||||
// Typelock functions. Use these when you want to make sure the property has the given type.
|
||||
void typelock( EPropTypes type );
|
||||
void typeloose();
|
||||
|
||||
private:
|
||||
// resolve-as functions. References the data, whereever it is.
|
||||
i32& asInteger();
|
||||
float& asFloat();
|
||||
CStr& asString();
|
||||
CVector3D& asVector();
|
||||
|
||||
// to functions. Convert whatever this is now to the chosen type.
|
||||
i32 toInteger();
|
||||
float toFloat();
|
||||
CStr toString();
|
||||
CVector3D toVector();
|
||||
void* toVoid();
|
||||
|
||||
// from functions. Convert the given value to whatever type this is now.
|
||||
void fromInteger( i32 value );
|
||||
void fromFloat( float value );
|
||||
void fromString( CStr& value );
|
||||
void fromVector( CVector3D& value );
|
||||
void fromVoid( void* value );
|
||||
struct SProperty_StringModifier
|
||||
{
|
||||
CStr replacement;
|
||||
void operator=( const CStr& value )
|
||||
{
|
||||
replacement = value;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -16,12 +16,18 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, float timestep )
|
||||
|
||||
float len = delta.length();
|
||||
|
||||
// janwas added EVIL HACK: BoundsChecker complains about NaNs
|
||||
// in atan2 and fabs => delta must be 0 somewhere.
|
||||
// currently skip over all math code that would break.
|
||||
// what's the real solution?
|
||||
if(len == 0.0f)
|
||||
goto small_delta;
|
||||
// ... 'Are we there yet?' ...
|
||||
|
||||
if( len < 0.1f )
|
||||
{
|
||||
if( current->m_type == CEntityOrder::ORDER_GOTO_COLLISION )
|
||||
{
|
||||
repath();
|
||||
}
|
||||
else
|
||||
m_orderQueue.pop_front();
|
||||
return( false );
|
||||
}
|
||||
|
||||
// Curve smoothing.
|
||||
// Here there be trig.
|
||||
@ -44,7 +50,7 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, float timestep )
|
||||
{
|
||||
m_targetorientation = atan2( delta.x, delta.y );
|
||||
|
||||
float deltatheta = m_targetorientation - m_orientation;
|
||||
float deltatheta = m_targetorientation - (float)m_orientation;
|
||||
while( deltatheta > PI ) deltatheta -= 2 * PI;
|
||||
while( deltatheta < -PI ) deltatheta += 2 * PI;
|
||||
|
||||
@ -53,10 +59,10 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, float timestep )
|
||||
float maxTurningSpeed = ( m_speed / m_turningRadius ) * timestep;
|
||||
if( deltatheta > 0 )
|
||||
{
|
||||
m_orientation += MIN( deltatheta, maxTurningSpeed );
|
||||
m_orientation = m_orientation + MIN( deltatheta, maxTurningSpeed );
|
||||
}
|
||||
else
|
||||
m_orientation += MAX( deltatheta, -maxTurningSpeed );
|
||||
m_orientation = m_orientation + MAX( deltatheta, -maxTurningSpeed );
|
||||
|
||||
m_ahead.x = sin( m_orientation );
|
||||
m_ahead.y = cos( m_orientation );
|
||||
@ -68,33 +74,11 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, float timestep )
|
||||
}
|
||||
}
|
||||
|
||||
if( len < 0.1f )
|
||||
{
|
||||
small_delta:
|
||||
if( current->m_type == CEntityOrder::ORDER_GOTO_COLLISION )
|
||||
{
|
||||
// Repath.
|
||||
CVector2D destination;
|
||||
while( !m_orderQueue.empty() &&
|
||||
( ( m_orderQueue.front().m_type == CEntityOrder::ORDER_GOTO_COLLISION )
|
||||
|| ( m_orderQueue.front().m_type == CEntityOrder::ORDER_GOTO_NOPATHING )
|
||||
|| ( m_orderQueue.front().m_type == CEntityOrder::ORDER_GOTO_SMOOTHED ) ) )
|
||||
{
|
||||
destination = m_orderQueue.front().m_data[0].location;
|
||||
m_orderQueue.pop_front();
|
||||
}
|
||||
g_Pathfinder.requestPath( me, destination );
|
||||
}
|
||||
else
|
||||
m_orderQueue.pop_front();
|
||||
return( false );
|
||||
}
|
||||
|
||||
if( m_bounds->m_type == CBoundingObject::BOUND_OABB )
|
||||
((CBoundingBox*)m_bounds)->setOrientation( m_ahead );
|
||||
|
||||
|
||||
float scale = timestep * m_speed;
|
||||
float scale = m_speed * timestep;
|
||||
|
||||
if( scale > len )
|
||||
scale = len;
|
||||
|
@ -5,8 +5,6 @@
|
||||
sparsePathTree::sparsePathTree( const CVector2D& _from, const CVector2D& _to, HEntity _entity, CBoundingObject* _destinationCollisionObject )
|
||||
{
|
||||
from = _from; to = _to;
|
||||
assert( from.length() > 0.01f );
|
||||
assert( to.length() > 0.01f );
|
||||
|
||||
entity = _entity; destinationCollisionObject = _destinationCollisionObject;
|
||||
leftPre = NULL; leftPost = NULL;
|
||||
@ -46,7 +44,7 @@ bool sparsePathTree::slice()
|
||||
|
||||
float turningRadius = ( entity->m_bounds->m_radius + r.boundingObject->m_radius ) * 1.1f;
|
||||
|
||||
if( turningRadius < entity->m_turningRadius ) turningRadius = entity->m_turningRadius;
|
||||
if( entity->m_turningRadius > turningRadius ) turningRadius = entity->m_turningRadius;
|
||||
|
||||
// Too close, an impossible turn
|
||||
if( r.distance < turningRadius )
|
||||
|
68
source/simulation/scripting/JSInterface_BaseEntity.cpp
Executable file
68
source/simulation/scripting/JSInterface_BaseEntity.cpp
Executable file
@ -0,0 +1,68 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "JSInterface_BaseEntity.h"
|
||||
#include "BaseEntity.h"
|
||||
#include "EntityHandles.h"
|
||||
|
||||
JSClass JSI_BaseEntity::JSI_class = {
|
||||
"EntityTemplate", JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JSI_BaseEntity::getProperty, JSI_BaseEntity::setProperty,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JS_ConvertStub, NULL,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
JSPropertySpec JSI_BaseEntity::JSI_props[] =
|
||||
{
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSFunctionSpec JSI_BaseEntity::JSI_methods[] =
|
||||
{
|
||||
{ "toString", JSI_BaseEntity::toString, 0, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSBool JSI_BaseEntity::getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
|
||||
{
|
||||
CBaseEntity* e = (CBaseEntity*)JS_GetPrivate( cx, obj );
|
||||
CStr propName = g_ScriptingHost.ValueToString( id );
|
||||
|
||||
if( e->m_properties.find( propName ) != e->m_properties.end() )
|
||||
{
|
||||
*vp = *(e->m_properties[propName]);
|
||||
return( JS_TRUE );
|
||||
}
|
||||
return( JS_TRUE );
|
||||
}
|
||||
|
||||
JSBool JSI_BaseEntity::setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
|
||||
{
|
||||
CBaseEntity* e = (CBaseEntity*)JS_GetPrivate( cx, obj );
|
||||
CStr propName = g_ScriptingHost.ValueToString( id );
|
||||
|
||||
if( e->m_properties.find( propName ) != e->m_properties.end() )
|
||||
{
|
||||
*(e->m_properties[propName]) = *vp;
|
||||
e->rebuild( propName );
|
||||
return( JS_TRUE );
|
||||
}
|
||||
return( JS_TRUE );
|
||||
}
|
||||
|
||||
void JSI_BaseEntity::init()
|
||||
{
|
||||
g_ScriptingHost.DefineCustomObjectType( &JSI_class, NULL, 0, JSI_props, JSI_methods, NULL, NULL );
|
||||
}
|
||||
|
||||
JSBool JSI_BaseEntity::toString( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
CBaseEntity* e = (CBaseEntity*)JS_GetPrivate( cx, obj );
|
||||
|
||||
char buffer[256];
|
||||
snprintf( buffer, 256, "[object EntityTemplate: %s]", (const TCHAR*)e->m_name );
|
||||
buffer[255] = 0;
|
||||
*rval = STRING_TO_JSVAL( JS_NewStringCopyZ( cx, buffer ) );
|
||||
return( JS_TRUE );
|
||||
}
|
30
source/simulation/scripting/JSInterface_BaseEntity.h
Executable file
30
source/simulation/scripting/JSInterface_BaseEntity.h
Executable file
@ -0,0 +1,30 @@
|
||||
// JSInterface_BaseEntity.h
|
||||
//
|
||||
// Last modified: 08 June 04, Mark Thompson mot20@cam.ac.uk / mark@wildfiregames.com
|
||||
//
|
||||
// An interface between CBaseEntity and the JavaScript class EntityTemplate
|
||||
//
|
||||
// Usage: Used when manipulating objects of class 'EntityTemplate' in JavaScript.
|
||||
//
|
||||
// Mark Thompson mot20@cam.ac.uk / mark@wildfiregames.com
|
||||
|
||||
#include "scripting/ScriptingHost.h"
|
||||
|
||||
#ifndef JSI_BASEENTITY_INCLUDED
|
||||
#define JSI_BASEENTITY_INCLUDED
|
||||
|
||||
namespace JSI_BaseEntity
|
||||
{
|
||||
JSBool toString( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
|
||||
extern JSClass JSI_class;
|
||||
extern JSPropertySpec JSI_props[];
|
||||
extern JSFunctionSpec JSI_methods[];
|
||||
JSBool addProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
|
||||
JSBool delProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
|
||||
JSBool getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
|
||||
JSBool setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
|
||||
void finalize( JSContext* cx, JSObject* obj );
|
||||
void init();
|
||||
};
|
||||
|
||||
#endif
|
136
source/simulation/scripting/JSInterface_Entity.cpp
Executable file
136
source/simulation/scripting/JSInterface_Entity.cpp
Executable file
@ -0,0 +1,136 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "JSInterface_Entity.h"
|
||||
#include "scripting/JSInterface_BaseEntity.h"
|
||||
#include "scripting/JSInterface_Vector3D.h"
|
||||
#include "EntityHandles.h"
|
||||
#include "Entity.h"
|
||||
#include "EntityManager.h"
|
||||
#include "BaseEntityCollection.h"
|
||||
#include "CConsole.h"
|
||||
|
||||
JSClass JSI_Entity::JSI_class = {
|
||||
"Entity", JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JSI_Entity::getProperty, JSI_Entity::setProperty,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JS_ConvertStub, JSI_Entity::finalize,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
JSPropertySpec JSI_Entity::JSI_props[] =
|
||||
{
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSFunctionSpec JSI_Entity::JSI_methods[] =
|
||||
{
|
||||
{ "toString", JSI_Entity::toString, 0, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
JSBool JSI_Entity::getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
|
||||
{
|
||||
HEntity* e = (HEntity*)JS_GetPrivate( cx, obj );
|
||||
if( !e )
|
||||
{
|
||||
*vp = JSVAL_NULL;
|
||||
return( JS_TRUE );
|
||||
}
|
||||
CStr propName = g_ScriptingHost.ValueToString( id );
|
||||
|
||||
if( (*e)->m_properties.find( propName ) != (*e)->m_properties.end() )
|
||||
{
|
||||
*vp = *((*e)->m_properties[propName]);
|
||||
return( JS_TRUE );
|
||||
}
|
||||
return( JS_TRUE );
|
||||
}
|
||||
|
||||
JSBool JSI_Entity::setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
|
||||
{
|
||||
HEntity* e = (HEntity*)JS_GetPrivate( cx, obj );
|
||||
CStr propName = g_ScriptingHost.ValueToString( id );
|
||||
|
||||
if( (*e)->m_properties.find( propName ) != (*e)->m_properties.end() )
|
||||
{
|
||||
*((*e)->m_properties[propName]) = *vp;
|
||||
(*e)->rebuild( propName );
|
||||
return( JS_TRUE );
|
||||
}
|
||||
return( JS_TRUE );
|
||||
}
|
||||
|
||||
JSBool JSI_Entity::construct( JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
assert( argc >= 2 );
|
||||
CBaseEntity* baseEntity;
|
||||
CVector3D position;
|
||||
float orientation = 0.0f;
|
||||
JSObject* jsBaseEntity = JSVAL_TO_OBJECT( argv[0] );
|
||||
if( JSVAL_IS_OBJECT( argv[0] ) && ( JS_GetClass( jsBaseEntity ) == &JSI_BaseEntity::JSI_class ) )
|
||||
{
|
||||
baseEntity = (CBaseEntity*)JS_GetPrivate( cx, jsBaseEntity );
|
||||
}
|
||||
else
|
||||
{
|
||||
CStr templateName;
|
||||
try
|
||||
{
|
||||
templateName = g_ScriptingHost.ValueToString( argv[0] );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
*rval = JSVAL_NULL;
|
||||
return( JS_TRUE );
|
||||
}
|
||||
baseEntity = g_EntityTemplateCollection.getTemplate( templateName );
|
||||
}
|
||||
if( !baseEntity )
|
||||
{
|
||||
*rval = JSVAL_NULL;
|
||||
return( JS_TRUE );
|
||||
}
|
||||
JSObject* jsVector3D = JSVAL_TO_OBJECT( argv[1] );
|
||||
if( JSVAL_IS_OBJECT( argv[1] ) && ( JS_GetClass( jsVector3D ) == &JSI_Vector3D::JSI_class ) )
|
||||
position = *( ( (JSI_Vector3D::Vector3D_Info*)JS_GetPrivate( cx, jsVector3D ) )->vector );
|
||||
if( argc >= 3 )
|
||||
{
|
||||
try
|
||||
{
|
||||
orientation = (float)g_ScriptingHost.ValueToDouble( argv[2] );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
orientation = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
HEntity* handle = new HEntity( g_EntityManager.create( baseEntity, position, orientation ) );
|
||||
(*handle)->dispatch( &CMessage( CMessage::EMSG_INIT ) );
|
||||
JSObject* entity = JS_NewObject( cx, &JSI_Entity::JSI_class, NULL, NULL );
|
||||
JS_SetPrivate( cx, entity, handle );
|
||||
*rval = OBJECT_TO_JSVAL( entity );
|
||||
return( JS_TRUE );
|
||||
}
|
||||
|
||||
void JSI_Entity::finalize( JSContext* cx, JSObject* obj )
|
||||
{
|
||||
delete( JS_GetPrivate( cx, obj ) );
|
||||
}
|
||||
|
||||
void JSI_Entity::init()
|
||||
{
|
||||
g_ScriptingHost.DefineCustomObjectType( &JSI_class, construct, 2, JSI_props, JSI_methods, NULL, NULL );
|
||||
}
|
||||
|
||||
JSBool JSI_Entity::toString( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
HEntity* e = (HEntity*)JS_GetPrivate( cx, obj );
|
||||
|
||||
char buffer[256];
|
||||
snprintf( buffer, 256, "[object Entity: \"%s\" (%s)]", (const TCHAR*)(*e)->m_name, (const TCHAR*)(*e)->m_base->m_name );
|
||||
buffer[255] = 0;
|
||||
*rval = STRING_TO_JSVAL( JS_NewStringCopyZ( cx, buffer ) );
|
||||
return( JS_TRUE );
|
||||
}
|
31
source/simulation/scripting/JSInterface_Entity.h
Executable file
31
source/simulation/scripting/JSInterface_Entity.h
Executable file
@ -0,0 +1,31 @@
|
||||
// JSInterface_Entity.h
|
||||
//
|
||||
// Last modified: 03 June 04, Mark Thompson mot20@cam.ac.uk / mark@wildfiregames.com
|
||||
//
|
||||
// The interface layer between JavaScript code and the actual CEntity object.
|
||||
//
|
||||
// Usage: Used when manipulating objects of class 'Entity' in JavaScript.
|
||||
//
|
||||
// Mark Thompson mot20@cam.ac.uk / mark@wildfiregames.com
|
||||
|
||||
#include "scripting/ScriptingHost.h"
|
||||
|
||||
#ifndef JSI_ENTITY_INCLUDED
|
||||
#define JSI_ENTITY_INCLUDED
|
||||
|
||||
namespace JSI_Entity
|
||||
{
|
||||
JSBool toString( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval );
|
||||
extern JSClass JSI_class;
|
||||
extern JSPropertySpec JSI_props[];
|
||||
extern JSFunctionSpec JSI_methods[];
|
||||
JSBool addProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
|
||||
JSBool delProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
|
||||
JSBool getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
|
||||
JSBool setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );
|
||||
JSBool construct( JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval );
|
||||
void finalize( JSContext* cx, JSObject* obj );
|
||||
void init();
|
||||
};
|
||||
|
||||
#endif
|
@ -23,6 +23,7 @@ package.files = {
|
||||
{ sourcesfromdirs("../../ps") },
|
||||
-- simulation/
|
||||
{ sourcesfromdirs("../../simulation") },
|
||||
{ sourcesfromdirs("../../simulation/scripting") },
|
||||
-- lib/
|
||||
{ sourcesfromdirs(
|
||||
"../../lib",
|
||||
@ -34,6 +35,7 @@ package.files = {
|
||||
-- maths/
|
||||
{ sourcesfromdirs(
|
||||
"../../maths") },
|
||||
{ sourcesfromdirs( "../../maths/scripting" ) },
|
||||
-- renderer/
|
||||
{ sourcesfromdirs(
|
||||
"../../renderer") },
|
||||
|
Loading…
Reference in New Issue
Block a user