Working on tree pannel from angelscriptgit add .!

This commit is contained in:
Arnau Alier Torres 2025-05-03 00:19:06 +02:00
parent 0ce75eeec8
commit 5d7025e141
13 changed files with 1197 additions and 54 deletions

View File

@ -0,0 +1,76 @@
#ifndef SCRIPTANY_H
#define SCRIPTANY_H
#ifndef ANGELSCRIPT_H
// Avoid having to inform include path if header is already include before
#include <angelscript.h>
#endif
BEGIN_AS_NAMESPACE
class CScriptAny
{
public:
// Constructors
CScriptAny(asIScriptEngine *engine);
CScriptAny(void *ref, int refTypeId, asIScriptEngine *engine);
// Memory management
int AddRef() const;
int Release() const;
// Copy the stored value from another any object
CScriptAny &operator=(const CScriptAny&);
int CopyFrom(const CScriptAny *other);
// Store the value, either as variable type, integer number, or real number
void Store(void *ref, int refTypeId);
void Store(asINT64 &value);
void Store(double &value);
// Retrieve the stored value, either as variable type, integer number, or real number
bool Retrieve(void *ref, int refTypeId) const;
bool Retrieve(asINT64 &value) const;
bool Retrieve(double &value) const;
// Get the type id of the stored value
int GetTypeId() const;
// GC methods
int GetRefCount();
void SetFlag();
bool GetFlag();
void EnumReferences(asIScriptEngine *engine);
void ReleaseAllHandles(asIScriptEngine *engine);
protected:
virtual ~CScriptAny();
void FreeObject();
mutable int refCount;
mutable bool gcFlag;
asIScriptEngine *engine;
// The structure for holding the values
struct valueStruct
{
union
{
asINT64 valueInt;
double valueFlt;
void *valueObj;
};
int typeId;
};
valueStruct value;
};
void RegisterScriptAny(asIScriptEngine *engine);
void RegisterScriptAny_Native(asIScriptEngine *engine);
void RegisterScriptAny_Generic(asIScriptEngine *engine);
END_AS_NAMESPACE
#endif

View File

@ -0,0 +1,69 @@
#ifndef SCRIPTHANDLE_H
#define SCRIPTHANDLE_H
#ifndef ANGELSCRIPT_H
// Avoid having to inform include path if header is already include before
#include <angelscript.h>
#endif
BEGIN_AS_NAMESPACE
class CScriptHandle
{
public:
// Constructors
CScriptHandle();
CScriptHandle(const CScriptHandle &other);
CScriptHandle(void *ref, asITypeInfo *type);
~CScriptHandle();
// Copy the stored value from another any object
CScriptHandle &operator=(const CScriptHandle &other);
// Set the reference
void Set(void *ref, asITypeInfo *type);
// Compare equalness
bool operator==(const CScriptHandle &o) const;
bool operator!=(const CScriptHandle &o) const;
bool Equals(void *ref, int typeId) const;
// Dynamic cast to desired handle type
void Cast(void **outRef, int typeId);
// Returns the type of the reference held
asITypeInfo *GetType() const;
int GetTypeId() const;
// Get the reference
void *GetRef();
// GC callback
void EnumReferences(asIScriptEngine *engine);
void ReleaseReferences(asIScriptEngine *engine);
protected:
// These functions need to have access to protected
// members in order to call them from the script engine
friend void Construct(CScriptHandle *self, void *ref, int typeId);
friend void RegisterScriptHandle_Native(asIScriptEngine *engine);
friend void CScriptHandle_AssignVar_Generic(asIScriptGeneric *gen);
void ReleaseHandle();
void AddRefHandle();
// These shouldn't be called directly by the
// application as they requires an active context
CScriptHandle(void *ref, int typeId);
CScriptHandle &Assign(void *ref, int typeId);
void *m_ref;
asITypeInfo *m_type;
};
void RegisterScriptHandle(asIScriptEngine *engine);
END_AS_NAMESPACE
#endif

View File

@ -0,0 +1,490 @@
#include "scriptany.h"
#include <new>
#include <assert.h>
#include <string.h>
BEGIN_AS_NAMESPACE
// We'll use the generic interface for the factories as we need the engine pointer
static void ScriptAnyFactory_Generic(asIScriptGeneric *gen)
{
asIScriptEngine *engine = gen->GetEngine();
*(CScriptAny**)gen->GetAddressOfReturnLocation() = new CScriptAny(engine);
}
static void ScriptAnyFactory2_Generic(asIScriptGeneric *gen)
{
asIScriptEngine *engine = gen->GetEngine();
void *ref = (void*)gen->GetArgAddress(0);
int refType = gen->GetArgTypeId(0);
*(CScriptAny**)gen->GetAddressOfReturnLocation() = new CScriptAny(ref,refType,engine);
}
static CScriptAny &ScriptAnyAssignment(CScriptAny *other, CScriptAny *self)
{
return *self = *other;
}
static void ScriptAnyAssignment_Generic(asIScriptGeneric *gen)
{
CScriptAny *other = (CScriptAny*)gen->GetArgObject(0);
CScriptAny *self = (CScriptAny*)gen->GetObject();
*self = *other;
gen->SetReturnObject(self);
}
static void ScriptAny_Store_Generic(asIScriptGeneric *gen)
{
void *ref = (void*)gen->GetArgAddress(0);
int refTypeId = gen->GetArgTypeId(0);
CScriptAny *self = (CScriptAny*)gen->GetObject();
self->Store(ref, refTypeId);
}
static void ScriptAny_StoreInt_Generic(asIScriptGeneric *gen)
{
asINT64 *ref = (asINT64*)gen->GetArgAddress(0);
CScriptAny *self = (CScriptAny*)gen->GetObject();
self->Store(*ref);
}
static void ScriptAny_StoreFlt_Generic(asIScriptGeneric *gen)
{
double *ref = (double*)gen->GetArgAddress(0);
CScriptAny *self = (CScriptAny*)gen->GetObject();
self->Store(*ref);
}
static void ScriptAny_Retrieve_Generic(asIScriptGeneric *gen)
{
void *ref = (void*)gen->GetArgAddress(0);
int refTypeId = gen->GetArgTypeId(0);
CScriptAny *self = (CScriptAny*)gen->GetObject();
*(bool*)gen->GetAddressOfReturnLocation() = self->Retrieve(ref, refTypeId);
}
static void ScriptAny_RetrieveInt_Generic(asIScriptGeneric *gen)
{
asINT64 *ref = (asINT64*)gen->GetArgAddress(0);
CScriptAny *self = (CScriptAny*)gen->GetObject();
*(bool*)gen->GetAddressOfReturnLocation() = self->Retrieve(*ref);
}
static void ScriptAny_RetrieveFlt_Generic(asIScriptGeneric *gen)
{
double *ref = (double*)gen->GetArgAddress(0);
CScriptAny *self = (CScriptAny*)gen->GetObject();
*(bool*)gen->GetAddressOfReturnLocation() = self->Retrieve(*ref);
}
static void ScriptAny_AddRef_Generic(asIScriptGeneric *gen)
{
CScriptAny *self = (CScriptAny*)gen->GetObject();
self->AddRef();
}
static void ScriptAny_Release_Generic(asIScriptGeneric *gen)
{
CScriptAny *self = (CScriptAny*)gen->GetObject();
self->Release();
}
static void ScriptAny_GetRefCount_Generic(asIScriptGeneric *gen)
{
CScriptAny *self = (CScriptAny*)gen->GetObject();
*(int*)gen->GetAddressOfReturnLocation() = self->GetRefCount();
}
static void ScriptAny_SetFlag_Generic(asIScriptGeneric *gen)
{
CScriptAny *self = (CScriptAny*)gen->GetObject();
self->SetFlag();
}
static void ScriptAny_GetFlag_Generic(asIScriptGeneric *gen)
{
CScriptAny *self = (CScriptAny*)gen->GetObject();
*(bool*)gen->GetAddressOfReturnLocation() = self->GetFlag();
}
static void ScriptAny_EnumReferences_Generic(asIScriptGeneric *gen)
{
CScriptAny *self = (CScriptAny*)gen->GetObject();
asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0);
self->EnumReferences(engine);
}
static void ScriptAny_ReleaseAllHandles_Generic(asIScriptGeneric *gen)
{
CScriptAny *self = (CScriptAny*)gen->GetObject();
asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0);
self->ReleaseAllHandles(engine);
}
void RegisterScriptAny(asIScriptEngine *engine)
{
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
RegisterScriptAny_Generic(engine);
else
RegisterScriptAny_Native(engine);
}
void RegisterScriptAny_Native(asIScriptEngine *engine)
{
int r;
r = engine->RegisterObjectType("any", sizeof(CScriptAny), asOBJ_REF | asOBJ_GC); assert( r >= 0 );
// We'll use the generic interface for the constructor as we need the engine pointer
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f()", asFUNCTION(ScriptAnyFactory_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f(?&in) explicit", asFUNCTION(ScriptAnyFactory2_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f(const int64&in) explicit", asFUNCTION(ScriptAnyFactory2_Generic), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f(const double&in) explicit", asFUNCTION(ScriptAnyFactory2_Generic), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectBehaviour("any", asBEHAVE_ADDREF, "void f()", asMETHOD(CScriptAny,AddRef), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_RELEASE, "void f()", asMETHOD(CScriptAny,Release), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "any &opAssign(any&in)", asFUNCTION(ScriptAnyAssignment), asCALL_CDECL_OBJLAST); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "void store(?&in)", asMETHODPR(CScriptAny,Store,(void*,int),void), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "void store(const int64&in)", asMETHODPR(CScriptAny,Store,(asINT64&),void), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "void store(const double&in)", asMETHODPR(CScriptAny,Store,(double&),void), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "bool retrieve(?&out)", asMETHODPR(CScriptAny,Retrieve,(void*,int) const,bool), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "bool retrieve(int64&out)", asMETHODPR(CScriptAny,Retrieve,(asINT64&) const,bool), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "bool retrieve(double&out)", asMETHODPR(CScriptAny,Retrieve,(double&) const,bool), asCALL_THISCALL); assert( r >= 0 );
// Register GC behaviours
r = engine->RegisterObjectBehaviour("any", asBEHAVE_GETREFCOUNT, "int f()", asMETHOD(CScriptAny,GetRefCount), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_SETGCFLAG, "void f()", asMETHOD(CScriptAny,SetFlag), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(CScriptAny,GetFlag), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(CScriptAny,EnumReferences), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(CScriptAny,ReleaseAllHandles), asCALL_THISCALL); assert( r >= 0 );
}
void RegisterScriptAny_Generic(asIScriptEngine *engine)
{
int r;
r = engine->RegisterObjectType("any", sizeof(CScriptAny), asOBJ_REF | asOBJ_GC); assert( r >= 0 );
// We'll use the generic interface for the constructor as we need the engine pointer
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f()", asFUNCTION(ScriptAnyFactory_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f(?&in) explicit", asFUNCTION(ScriptAnyFactory2_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f(const int64&in) explicit", asFUNCTION(ScriptAnyFactory2_Generic), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f(const double&in) explicit", asFUNCTION(ScriptAnyFactory2_Generic), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectBehaviour("any", asBEHAVE_ADDREF, "void f()", asFUNCTION(ScriptAny_AddRef_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_RELEASE, "void f()", asFUNCTION(ScriptAny_Release_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "any &opAssign(any&in)", asFUNCTION(ScriptAnyAssignment_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "void store(?&in)", asFUNCTION(ScriptAny_Store_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "void store(const int64&in)", asFUNCTION(ScriptAny_StoreInt_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "void store(const double&in)", asFUNCTION(ScriptAny_StoreFlt_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "bool retrieve(?&out) const", asFUNCTION(ScriptAny_Retrieve_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "bool retrieve(int64&out) const", asFUNCTION(ScriptAny_RetrieveInt_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod("any", "bool retrieve(double&out) const", asFUNCTION(ScriptAny_RetrieveFlt_Generic), asCALL_GENERIC); assert( r >= 0 );
// Register GC behaviours
r = engine->RegisterObjectBehaviour("any", asBEHAVE_GETREFCOUNT, "int f()", asFUNCTION(ScriptAny_GetRefCount_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_SETGCFLAG, "void f()", asFUNCTION(ScriptAny_SetFlag_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_GETGCFLAG, "bool f()", asFUNCTION(ScriptAny_GetFlag_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(ScriptAny_EnumReferences_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("any", asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(ScriptAny_ReleaseAllHandles_Generic), asCALL_GENERIC); assert( r >= 0 );
}
CScriptAny &CScriptAny::operator=(const CScriptAny &other)
{
// Hold on to the object type reference so it isn't destroyed too early
if( (other.value.typeId & asTYPEID_MASK_OBJECT) )
{
asITypeInfo *ti = engine->GetTypeInfoById(other.value.typeId);
if( ti )
ti->AddRef();
}
FreeObject();
value.typeId = other.value.typeId;
if( value.typeId & asTYPEID_OBJHANDLE )
{
// For handles, copy the pointer and increment the reference count
value.valueObj = other.value.valueObj;
engine->AddRefScriptObject(value.valueObj, engine->GetTypeInfoById(value.typeId));
}
else if( value.typeId & asTYPEID_MASK_OBJECT )
{
// Create a copy of the object
value.valueObj = engine->CreateScriptObjectCopy(other.value.valueObj, engine->GetTypeInfoById(value.typeId));
}
else
{
// Primitives can be copied directly
value.valueInt = other.value.valueInt;
}
return *this;
}
int CScriptAny::CopyFrom(const CScriptAny *other)
{
if( other == 0 ) return asINVALID_ARG;
*this = *other;
return 0;
}
CScriptAny::CScriptAny(asIScriptEngine *engine)
{
this->engine = engine;
refCount = 1;
gcFlag = false;
value.typeId = 0;
value.valueInt = 0;
// Notify the garbage collector of this object
engine->NotifyGarbageCollectorOfNewObject(this, engine->GetTypeInfoByName("any"));
}
CScriptAny::CScriptAny(void *ref, int refTypeId, asIScriptEngine *engine)
{
this->engine = engine;
refCount = 1;
gcFlag = false;
value.typeId = 0;
value.valueInt = 0;
// Notify the garbage collector of this object
engine->NotifyGarbageCollectorOfNewObject(this, engine->GetTypeInfoByName("any"));
Store(ref, refTypeId);
}
CScriptAny::~CScriptAny()
{
FreeObject();
}
void CScriptAny::Store(void *ref, int refTypeId)
{
// This method is not expected to be used for primitive types, except for bool, int64, or double
assert( refTypeId > asTYPEID_DOUBLE || refTypeId == asTYPEID_VOID || refTypeId == asTYPEID_BOOL || refTypeId == asTYPEID_INT64 || refTypeId == asTYPEID_DOUBLE );
// Hold on to the object type reference so it isn't destroyed too early
if( (refTypeId & asTYPEID_MASK_OBJECT) )
{
asITypeInfo *ti = engine->GetTypeInfoById(refTypeId);
if( ti )
ti->AddRef();
}
FreeObject();
value.typeId = refTypeId;
if( value.typeId & asTYPEID_OBJHANDLE )
{
// We're receiving a reference to the handle, so we need to dereference it
value.valueObj = *(void**)ref;
engine->AddRefScriptObject(value.valueObj, engine->GetTypeInfoById(value.typeId));
}
else if( value.typeId & asTYPEID_MASK_OBJECT )
{
// Create a copy of the object
value.valueObj = engine->CreateScriptObjectCopy(ref, engine->GetTypeInfoById(value.typeId));
}
else
{
// Primitives can be copied directly
value.valueInt = 0;
// Copy the primitive value
// We receive a pointer to the value.
int size = engine->GetSizeOfPrimitiveType(value.typeId);
memcpy(&value.valueInt, ref, size);
}
}
void CScriptAny::Store(double &ref)
{
Store(&ref, asTYPEID_DOUBLE);
}
void CScriptAny::Store(asINT64 &ref)
{
Store(&ref, asTYPEID_INT64);
}
bool CScriptAny::Retrieve(void *ref, int refTypeId) const
{
// This method is not expected to be used for primitive types, except for bool, int64, or double
assert( refTypeId > asTYPEID_DOUBLE || refTypeId == asTYPEID_BOOL || refTypeId == asTYPEID_INT64 || refTypeId == asTYPEID_DOUBLE );
if( refTypeId & asTYPEID_OBJHANDLE )
{
// Is the handle type compatible with the stored value?
// A handle can be retrieved if the stored type is a handle of same or compatible type
// or if the stored type is an object that implements the interface that the handle refer to.
if( (value.typeId & asTYPEID_MASK_OBJECT) )
{
// Don't allow the retrieval if the stored handle is to a const object but not the wanted handle
if( (value.typeId & asTYPEID_HANDLETOCONST) && !(refTypeId & asTYPEID_HANDLETOCONST) )
return false;
// RefCastObject will increment the refCount of the returned pointer if successful
engine->RefCastObject(value.valueObj, engine->GetTypeInfoById(value.typeId), engine->GetTypeInfoById(refTypeId), reinterpret_cast<void**>(ref));
if( *(asPWORD*)ref == 0 )
return false;
return true;
}
}
else if( refTypeId & asTYPEID_MASK_OBJECT )
{
// Is the object type compatible with the stored value?
// Copy the object into the given reference
if( value.typeId == refTypeId )
{
engine->AssignScriptObject(ref, value.valueObj, engine->GetTypeInfoById(value.typeId));
return true;
}
}
else
{
// Is the primitive type compatible with the stored value?
if( value.typeId == refTypeId )
{
int size = engine->GetSizeOfPrimitiveType(refTypeId);
memcpy(ref, &value.valueInt, size);
return true;
}
// We know all numbers are stored as either int64 or double, since we register overloaded functions for those
if( value.typeId == asTYPEID_INT64 && refTypeId == asTYPEID_DOUBLE )
{
*(double*)ref = double(value.valueInt);
return true;
}
else if( value.typeId == asTYPEID_DOUBLE && refTypeId == asTYPEID_INT64 )
{
*(asINT64*)ref = asINT64(value.valueFlt);
return true;
}
}
return false;
}
bool CScriptAny::Retrieve(asINT64 &outValue) const
{
return Retrieve(&outValue, asTYPEID_INT64);
}
bool CScriptAny::Retrieve(double &outValue) const
{
return Retrieve(&outValue, asTYPEID_DOUBLE);
}
int CScriptAny::GetTypeId() const
{
return value.typeId;
}
void CScriptAny::FreeObject()
{
// If it is a handle or a ref counted object, call release
if( value.typeId & asTYPEID_MASK_OBJECT )
{
// Let the engine release the object
asITypeInfo *ti = engine->GetTypeInfoById(value.typeId);
engine->ReleaseScriptObject(value.valueObj, ti);
// Release the object type info
if( ti )
ti->Release();
value.valueObj = 0;
value.typeId = 0;
}
// For primitives, there's nothing to do
}
void CScriptAny::EnumReferences(asIScriptEngine *inEngine)
{
// If we're holding a reference, we'll notify the garbage collector of it
if (value.valueObj && (value.typeId & asTYPEID_MASK_OBJECT))
{
asITypeInfo *subType = engine->GetTypeInfoById(value.typeId);
if ((subType->GetFlags() & asOBJ_REF))
{
inEngine->GCEnumCallback(value.valueObj);
}
else if ((subType->GetFlags() & asOBJ_VALUE) && (subType->GetFlags() & asOBJ_GC))
{
// For value types we need to forward the enum callback
// to the object so it can decide what to do
engine->ForwardGCEnumReferences(value.valueObj, subType);
}
// The object type itself is also garbage collected
asITypeInfo *ti = inEngine->GetTypeInfoById(value.typeId);
if (ti)
inEngine->GCEnumCallback(ti);
}
}
void CScriptAny::ReleaseAllHandles(asIScriptEngine * /*engine*/)
{
FreeObject();
}
int CScriptAny::AddRef() const
{
// Increase counter and clear flag set by GC
gcFlag = false;
return asAtomicInc(refCount);
}
int CScriptAny::Release() const
{
// Decrease the ref counter
gcFlag = false;
if( asAtomicDec(refCount) == 0 )
{
// Delete this object as no more references to it exists
delete this;
return 0;
}
return refCount;
}
int CScriptAny::GetRefCount()
{
return refCount;
}
void CScriptAny::SetFlag()
{
gcFlag = true;
}
bool CScriptAny::GetFlag()
{
return gcFlag;
}
END_AS_NAMESPACE

View File

@ -0,0 +1,360 @@
#include "scripthandle.h"
#include <new>
#include <assert.h>
#include <string.h>
BEGIN_AS_NAMESPACE
static void Construct(CScriptHandle *self) { new(self) CScriptHandle(); }
static void Construct(CScriptHandle *self, const CScriptHandle &o) { new(self) CScriptHandle(o); }
// This one is not static because it needs to be friend with the CScriptHandle class
void Construct(CScriptHandle *self, void *ref, int typeId) { new(self) CScriptHandle(ref, typeId); }
static void Destruct(CScriptHandle *self) { self->~CScriptHandle(); }
CScriptHandle::CScriptHandle()
{
m_ref = 0;
m_type = 0;
}
CScriptHandle::CScriptHandle(const CScriptHandle &other)
{
m_ref = other.m_ref;
m_type = other.m_type;
AddRefHandle();
}
CScriptHandle::CScriptHandle(void *ref, asITypeInfo *type)
{
m_ref = ref;
m_type = type;
AddRefHandle();
}
// This constructor shouldn't be called from the application
// directly as it requires an active script context
CScriptHandle::CScriptHandle(void *ref, int typeId)
{
m_ref = 0;
m_type = 0;
Assign(ref, typeId);
}
CScriptHandle::~CScriptHandle()
{
ReleaseHandle();
}
void CScriptHandle::ReleaseHandle()
{
if( m_ref && m_type )
{
asIScriptEngine *engine = m_type->GetEngine();
engine->ReleaseScriptObject(m_ref, m_type);
engine->Release();
m_ref = 0;
m_type = 0;
}
}
void CScriptHandle::AddRefHandle()
{
if( m_ref && m_type )
{
asIScriptEngine *engine = m_type->GetEngine();
engine->AddRefScriptObject(m_ref, m_type);
// Hold on to the engine so it isn't destroyed while
// a reference to a script object is still held
engine->AddRef();
}
}
CScriptHandle &CScriptHandle::operator =(const CScriptHandle &other)
{
Set(other.m_ref, other.m_type);
return *this;
}
void CScriptHandle::Set(void *ref, asITypeInfo *type)
{
if( m_ref == ref ) return;
ReleaseHandle();
m_ref = ref;
m_type = type;
AddRefHandle();
}
void *CScriptHandle::GetRef()
{
return m_ref;
}
asITypeInfo *CScriptHandle::GetType() const
{
return m_type;
}
int CScriptHandle::GetTypeId() const
{
if( m_type == 0 ) return 0;
return m_type->GetTypeId() | asTYPEID_OBJHANDLE;
}
// This method shouldn't be called from the application
// directly as it requires an active script context
CScriptHandle &CScriptHandle::Assign(void *ref, int typeId)
{
// When receiving a null handle we just clear our memory
if( typeId == 0 )
{
Set(0, 0);
return *this;
}
// Dereference received handles to get the object
if( typeId & asTYPEID_OBJHANDLE )
{
// Store the actual reference
ref = *(void**)ref;
typeId &= ~asTYPEID_OBJHANDLE;
}
// Get the object type
asIScriptContext *ctx = asGetActiveContext();
asIScriptEngine *engine = ctx->GetEngine();
asITypeInfo *type = engine->GetTypeInfoById(typeId);
// If the argument is another CScriptHandle, we should copy the content instead
if( type && strcmp(type->GetName(), "ref") == 0 )
{
CScriptHandle *r = (CScriptHandle*)ref;
ref = r->m_ref;
type = r->m_type;
}
Set(ref, type);
return *this;
}
bool CScriptHandle::operator==(const CScriptHandle &o) const
{
if( m_ref == o.m_ref &&
m_type == o.m_type )
return true;
// TODO: If type is not the same, we should attempt to do a dynamic cast,
// which may change the pointer for application registered classes
return false;
}
bool CScriptHandle::operator!=(const CScriptHandle &o) const
{
return !(*this == o);
}
bool CScriptHandle::Equals(void *ref, int typeId) const
{
// Null handles are received as reference to a null handle
if( typeId == 0 )
ref = 0;
// Dereference handles to get the object
if( typeId & asTYPEID_OBJHANDLE )
{
// Compare the actual reference
ref = *(void**)ref;
typeId &= ~asTYPEID_OBJHANDLE;
}
// TODO: If typeId is not the same, we should attempt to do a dynamic cast,
// which may change the pointer for application registered classes
if( ref == m_ref ) return true;
return false;
}
// AngelScript: used as '@obj = cast<obj>(ref);'
void CScriptHandle::Cast(void **outRef, int typeId)
{
// If we hold a null handle, then just return null
if( m_type == 0 )
{
*outRef = 0;
return;
}
// It is expected that the outRef is always a handle
assert( typeId & asTYPEID_OBJHANDLE );
// Compare the type id of the actual object
typeId &= ~asTYPEID_OBJHANDLE;
asIScriptEngine *engine = m_type->GetEngine();
asITypeInfo *type = engine->GetTypeInfoById(typeId);
*outRef = 0;
// RefCastObject will increment the refCount of the returned object if successful
engine->RefCastObject(m_ref, m_type, type, outRef);
}
void CScriptHandle::EnumReferences(asIScriptEngine *inEngine)
{
// If we're holding a reference, we'll notify the garbage collector of it
if (m_ref)
inEngine->GCEnumCallback(m_ref);
// The object type itself is also garbage collected
if( m_type)
inEngine->GCEnumCallback(m_type);
}
void CScriptHandle::ReleaseReferences(asIScriptEngine * /*inEngine*/)
{
// Simply clear the content to release the references
Set(0, 0);
}
void RegisterScriptHandle_Native(asIScriptEngine *engine)
{
int r;
#if AS_CAN_USE_CPP11
// With C++11 it is possible to use asGetTypeTraits to automatically determine the flags that represent the C++ class
r = engine->RegisterObjectType("ref", sizeof(CScriptHandle), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asGetTypeTraits<CScriptHandle>()); assert( r >= 0 );
#else
r = engine->RegisterObjectType("ref", sizeof(CScriptHandle), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asOBJ_APP_CLASS_CDAK); assert( r >= 0 );
#endif
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f()", asFUNCTIONPR(Construct, (CScriptHandle *), void), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ref &in)", asFUNCTIONPR(Construct, (CScriptHandle *, const CScriptHandle &), void), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ?&in)", asFUNCTIONPR(Construct, (CScriptHandle *, void *, int), void), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_DESTRUCT, "void f()", asFUNCTIONPR(Destruct, (CScriptHandle *), void), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(CScriptHandle,EnumReferences), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(CScriptHandle, ReleaseReferences), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("ref", "void opCast(?&out)", asMETHODPR(CScriptHandle, Cast, (void **, int), void), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ref &in)", asMETHOD(CScriptHandle, operator=), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ?&in)", asMETHOD(CScriptHandle, Assign), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ref &in) const", asMETHODPR(CScriptHandle, operator==, (const CScriptHandle &) const, bool), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ?&in) const", asMETHODPR(CScriptHandle, Equals, (void*, int) const, bool), asCALL_THISCALL); assert( r >= 0 );
}
void CScriptHandle_Construct_Generic(asIScriptGeneric *gen)
{
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
new(self) CScriptHandle();
}
void CScriptHandle_ConstructCopy_Generic(asIScriptGeneric *gen)
{
CScriptHandle *other = reinterpret_cast<CScriptHandle*>(gen->GetArgAddress(0));
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
new(self) CScriptHandle(*other);
}
void CScriptHandle_ConstructVar_Generic(asIScriptGeneric *gen)
{
void *ref = gen->GetArgAddress(0);
int typeId = gen->GetArgTypeId(0);
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
Construct(self, ref, typeId);
}
void CScriptHandle_Destruct_Generic(asIScriptGeneric *gen)
{
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
self->~CScriptHandle();
}
void CScriptHandle_Cast_Generic(asIScriptGeneric *gen)
{
void **ref = reinterpret_cast<void**>(gen->GetArgAddress(0));
int typeId = gen->GetArgTypeId(0);
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
self->Cast(ref, typeId);
}
void CScriptHandle_Assign_Generic(asIScriptGeneric *gen)
{
CScriptHandle *other = reinterpret_cast<CScriptHandle*>(gen->GetArgAddress(0));
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
*self = *other;
gen->SetReturnAddress(self);
}
void CScriptHandle_AssignVar_Generic(asIScriptGeneric *gen)
{
void *ref = gen->GetArgAddress(0);
int typeId = gen->GetArgTypeId(0);
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
self->Assign(ref, typeId);
gen->SetReturnAddress(self);
}
void CScriptHandle_Equals_Generic(asIScriptGeneric *gen)
{
CScriptHandle *other = reinterpret_cast<CScriptHandle*>(gen->GetArgAddress(0));
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
gen->SetReturnByte(*self == *other);
}
void CScriptHandle_EqualsVar_Generic(asIScriptGeneric *gen)
{
void *ref = gen->GetArgAddress(0);
int typeId = gen->GetArgTypeId(0);
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
gen->SetReturnByte(self->Equals(ref, typeId));
}
void CScriptHandle_EnumReferences_Generic(asIScriptGeneric *gen)
{
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
self->EnumReferences(gen->GetEngine());
}
void CScriptHandle_ReleaseReferences_Generic(asIScriptGeneric *gen)
{
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
self->ReleaseReferences(gen->GetEngine());
}
void RegisterScriptHandle_Generic(asIScriptEngine *engine)
{
int r;
r = engine->RegisterObjectType("ref", sizeof(CScriptHandle), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asOBJ_APP_CLASS_CDAK); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(CScriptHandle_Construct_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ref &in)", asFUNCTION(CScriptHandle_ConstructCopy_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ?&in)", asFUNCTION(CScriptHandle_ConstructVar_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(CScriptHandle_Destruct_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(CScriptHandle_EnumReferences_Generic), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(CScriptHandle_ReleaseReferences_Generic), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectMethod("ref", "void opCast(?&out)", asFUNCTION(CScriptHandle_Cast_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ref &in)", asFUNCTION(CScriptHandle_Assign_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ?&in)", asFUNCTION(CScriptHandle_AssignVar_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ref &in) const", asFUNCTION(CScriptHandle_Equals_Generic), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ?&in) const", asFUNCTION(CScriptHandle_EqualsVar_Generic), asCALL_GENERIC); assert( r >= 0 );
}
void RegisterScriptHandle(asIScriptEngine *engine)
{
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
RegisterScriptHandle_Generic(engine);
else
RegisterScriptHandle_Native(engine);
}
END_AS_NAMESPACE

View File

@ -1,16 +1,24 @@
#pragma once
#include <stdint.h>
#include <string>
namespace Deer {
namespace EditorEngine {
struct EntityStruct {
EntityStruct(uint16_t entId) : entityId(entId) { }
uint16_t entityId;
int getChildCount();
EntityStruct getChild(int);
std::string getName();
int getId();
};
EntityStruct getRoot();
int getChildCount(EntityStruct&);
EntityStruct getChild(EntityStruct&, int);
void constructEntityStruct(int id, void* memory);
void copyEntityStruct(int id, void* memory);
}
}

View File

@ -1,4 +1,16 @@
#pragma once
#include "DeerStudio/EditorEngine/API/EditorEngine_Button.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Column.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Directory.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Environment.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Environment.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Icon.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Input.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Mesh.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Text.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_MenuBar.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_TreeNode.h"
#include <string>
class asSMessageInfo;

View File

@ -2,10 +2,11 @@
#include <string>
class asIScriptFunction;
class CScriptAny;
namespace Deer {
namespace EditorEngine {
void treeNode(std::string&);
void treeNode(std::string&, asIScriptFunction);
void treeNode(std::string&, int);
void treeNodeRecursive(std::string&, int, CScriptAny*, asIScriptFunction&);
}
}

View File

@ -1,7 +1,55 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_Environment.h"
#include "DeerStudio/Project.h"
#include "Deer/Enviroment.h"
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/DockPanelObject.h"
#include "Deer/Scene.h"
namespace Deer {
namespace EditorEngine {
EntityStruct getRoot() {
return EntityStruct(0);
}
int EntityStruct::getChildCount() {
return Project::m_scene
.getMainEnviroment()
.getEntity(entityId)
.getComponent<RelationshipComponent>()
.childCount;
}
EntityStruct EntityStruct::getChild(int i) {
RelationshipComponent& rc = Project::m_scene
.getMainEnviroment()
.getEntity(entityId)
.getComponent<RelationshipComponent>();
if (i < 0 || i >= rc.childCount) {
DEER_UI_ENGINE_ERROR("Error while executing Entity.getChild(..), id {0} is invalid for child count of {1}", i, rc.childCount);
if (currentDockPanelExecution)
currentDockPanelExecution->invalidate();
return EntityStruct(0);
}
return EntityStruct(rc.getChildrenId(i));
}
void constructEntityStruct(int id, void* memory) {
new (memory)EntityStruct(id);
}
int EntityStruct::getId() {
return entityId;
}
std::string EntityStruct::getName() {
return Project::m_scene
.getMainEnviroment()
.getEntity(entityId)
.getComponent<TagComponent>()
.tag;
}
}
}

View File

@ -1,33 +1,50 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_TreeNode.h"
#include "DeerStudio/EditorEngine/EditorEngine_ErrorHandle.h"
#include "DeerStudio/EditorEngine.h"
#include "angelscript.h"
#include "scriptany.h"
#include "imgui.h"
namespace Deer {
namespace EditorEngine {
void treeNode(std::string& txt) {
void treeNode(std::string& txt, int id) {
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf |
ImGuiTreeNodeFlags_NoTreePushOnOpen |
ImGuiTreeNodeFlags_SpanFullWidth;
ImGui::TreeNodeEx((void*)0, flags, "%s", txt.c_str());
ImGui::TreeNodeEx((void*)(long long)id, flags, "%s", txt.c_str());
}
void treeNode(std::string& txt, asIScriptFunction& func) {
void treeNodeRecursive(std::string& txt, int id, CScriptAny *data, asIScriptFunction& func) {
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnDoubleClick |
ImGuiTreeNodeFlags_OpenOnArrow |
ImGuiTreeNodeFlags_SpanFullWidth;
if (ImGui::TreeNodeEx((void*)0, flags, "%s", txt.c_str())) {
if (ImGui::TreeNodeEx((void*)(long long)id, flags, "%s", txt.c_str())) {
ImGui::PushID(id);
if (scriptContext && scriptContext->PushState() == asSUCCESS) {
AS_CHECK_ADDITIONAL_INFO(
scriptContext->Prepare(&func),
func.GetDeclaration()
);
AS_CHECK_ADDITIONAL_INFO(
scriptContext->SetArgObject(0, data),
func.GetDeclaration()
);
AS_CHECK_ADDITIONAL_INFO(
scriptContext->Execute(),
func.GetDeclaration()
);
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::PopID();
ImGui::TreePop();
}
}

View File

@ -1,18 +1,6 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_Functions.h"
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/EditorEngine_ErrorHandle.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Button.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Column.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Directory.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Environment.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Environment.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Functions.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Functions.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Icon.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Input.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Mesh.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Text.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_MenuBar.h"
#include "angelscript.h"
@ -20,13 +8,13 @@ namespace Deer {
void EditorEngine::registerEditorEngineFunctions() {
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool menuItem(const string& in)",
asFUNCTION(Deer::EditorEngine::menuItem),
asFUNCTION(menuItem),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void textColor(float, float, float, const string& in)",
asFUNCTION(Deer::EditorEngine::textColor),
asFUNCTION(textColor),
asCALL_CDECL
));
@ -38,7 +26,7 @@ namespace Deer {
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void drawIcon(const string& in, int)",
asFUNCTION(Deer::EditorEngine::drawIcon),
asFUNCTION(drawIcon),
asCALL_CDECL
));
@ -80,56 +68,104 @@ namespace Deer {
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void print(const string& in)",
asFUNCTION (Deer::EditorEngine::print),
asFUNCTION (print),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void textCentered(const string& in)",
asFUNCTION(Deer::EditorEngine::textCentered),
asFUNCTION(textCentered),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void drawIconCentered(const string& in, int)",
asFUNCTION(Deer::EditorEngine::drawIconCentered),
asFUNCTION(drawIconCentered),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"int getResourceCount(ResourceType, const string& in)",
asFUNCTION(Deer::EditorEngine::getResourceCount),
asFUNCTION(getResourceCount),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"string getResourceNameById(ResourceType, const string& in, int)",
asFUNCTION(Deer::EditorEngine::getResourceNameById),
asFUNCTION(getResourceNameById),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"string getResourcePathById(ResourceType, const string& in, int)",
asFUNCTION(Deer::EditorEngine::getResourcePathById),
asFUNCTION(getResourcePathById),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"int getDirCount(ResourceType, const string& in)",
asFUNCTION(Deer::EditorEngine::getDirCount),
asFUNCTION(getDirCount),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"string getDirPathById(ResourceType, const string& in, int)",
asFUNCTION(Deer::EditorEngine::getDirPathById),
asFUNCTION(getDirPathById),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"string getDirNameById(ResourceType, const string& in, int)",
asFUNCTION(Deer::EditorEngine::getDirNameById),
asFUNCTION(getDirNameById),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void treeNode(const string& in, int)",
asFUNCTION(treeNode),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterFuncdef("void CallbackFunc(any@)"));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void treeNode(const string& in, int, any@+, CallbackFunc@+)",
asFUNCTION(treeNodeRecursive),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"Entity getRoot()",
asFUNCTION(getRoot),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"int getChildCount()",
asMETHOD(EntityStruct, getChildCount),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"Entity getChild(int)",
asMETHOD(EntityStruct, getChild),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"string getName()",
asMETHOD(EntityStruct, getName),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"int getId()",
asMETHOD(EntityStruct, getId),
asCALL_THISCALL
));
}
}

View File

@ -1,4 +1,6 @@
#include "DeerStudio/EditorEngine.h"
#include "scripthandle.h"
#include "scriptany.h"
#include "DeerStudio/EditorEngine/EditorEngine_ErrorHandle.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Mesh.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Environment.h"
@ -14,12 +16,24 @@ namespace Deer {
void registerEntityStruct() {
AS_CHECK(scriptEngine->RegisterObjectType("Entity", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>()));
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectBehaviour(
"Entity",
asBEHAVE_CONSTRUCT,
"void f(int)",
asFunctionPtr(constructEntityStruct),
asCALL_CDECL_OBJLAST
));
}
void registerEditorEngineStructs() {
RegisterScriptHandle(scriptEngine);
RegisterScriptAny(scriptEngine);
registerResourceTypeEnum();
registerEntityStruct();
}
}
}

View File

@ -6,11 +6,25 @@ class TreePannel : DockPanel {
}
void onRender() {
root = getRoot();
renderEntity(root);
Entity root = getRoot();
treeNode(root.getName(), root.getId(), any(root),CallbackFunc(this.render));
}
void renderEntity(Entity entity) {
void render(any@ data) {
Entity entity;
data.retrieve(entity);
int childCount = entity.getChildCount();
for (int i = 0; i < childCount; i++) {
Entity child = entity.getChild(i);
if (child.getChildCount() == 0) {
treeNode(child.getName(), child.getId());
} else {
treeNode(child.getName(), child.getId(), any(child),CallbackFunc(this.render));
}
}
}
}
}

View File

@ -9,14 +9,14 @@ Size=400,400
Collapsed=0
[Window][Properties]
Pos=968,24
Size=312,110
Pos=961,24
Size=319,392
Collapsed=0
DockId=0x00000009,0
DockId=0x00000004,0
[Window][Game Window]
Pos=304,24
Size=662,392
Size=655,392
Collapsed=0
DockId=0x00000006,1
@ -27,14 +27,14 @@ Collapsed=0
DockId=0x00000005,0
[Window][Terrain Editor]
Pos=968,136
Size=312,280
Pos=961,24
Size=319,392
Collapsed=0
DockId=0x0000000A,0
DockId=0x00000004,1
[Window][Viewport]
Pos=304,24
Size=662,392
Size=655,392
Collapsed=0
DockId=0x00000006,0
@ -72,12 +72,10 @@ DockId=0x00000005,1
DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=1280,696 Split=Y
DockNode ID=0x00000007 Parent=0xA1672E74 SizeRef=1280,392 Split=Y
DockNode ID=0x00000001 Parent=0x00000007 SizeRef=2560,363 Split=X Selected=0x13926F0B
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=966,779 Split=X Selected=0x13926F0B
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=959,779 Split=X Selected=0x13926F0B
DockNode ID=0x00000005 Parent=0x00000003 SizeRef=302,779 Selected=0xE45B9F93
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=662,779 CentralNode=1 Selected=0x13926F0B
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=312,779 Split=Y Selected=0x199AB496
DockNode ID=0x00000009 Parent=0x00000004 SizeRef=392,110 Selected=0x199AB496
DockNode ID=0x0000000A Parent=0x00000004 SizeRef=392,280 Selected=0x2A2C795E
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=655,779 CentralNode=1 Selected=0x13926F0B
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=319,779 Selected=0x199AB496
DockNode ID=0x00000002 Parent=0x00000007 SizeRef=2560,331 Selected=0xCF339702
DockNode ID=0x00000008 Parent=0xA1672E74 SizeRef=1280,302 Selected=0xD962995A