diff --git a/Deer/vendor/angelScript/include/scriptany.h b/Deer/vendor/angelScript/include/scriptany.h new file mode 100644 index 0000000..5b01099 --- /dev/null +++ b/Deer/vendor/angelScript/include/scriptany.h @@ -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 +#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 diff --git a/Deer/vendor/angelScript/include/scripthandle.h b/Deer/vendor/angelScript/include/scripthandle.h new file mode 100644 index 0000000..3066cef --- /dev/null +++ b/Deer/vendor/angelScript/include/scripthandle.h @@ -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 +#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 diff --git a/Deer/vendor/angelScript/src/scriptany.cpp b/Deer/vendor/angelScript/src/scriptany.cpp new file mode 100644 index 0000000..7a86c7a --- /dev/null +++ b/Deer/vendor/angelScript/src/scriptany.cpp @@ -0,0 +1,490 @@ +#include "scriptany.h" +#include +#include +#include + +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(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 diff --git a/Deer/vendor/angelScript/src/scripthandle.cpp b/Deer/vendor/angelScript/src/scripthandle.cpp new file mode 100644 index 0000000..576b20a --- /dev/null +++ b/Deer/vendor/angelScript/src/scripthandle.cpp @@ -0,0 +1,360 @@ +#include "scripthandle.h" +#include +#include +#include + +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(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()); 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(gen->GetObject()); + new(self) CScriptHandle(); +} + +void CScriptHandle_ConstructCopy_Generic(asIScriptGeneric *gen) +{ + CScriptHandle *other = reinterpret_cast(gen->GetArgAddress(0)); + CScriptHandle *self = reinterpret_cast(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(gen->GetObject()); + Construct(self, ref, typeId); +} + +void CScriptHandle_Destruct_Generic(asIScriptGeneric *gen) +{ + CScriptHandle *self = reinterpret_cast(gen->GetObject()); + self->~CScriptHandle(); +} + +void CScriptHandle_Cast_Generic(asIScriptGeneric *gen) +{ + void **ref = reinterpret_cast(gen->GetArgAddress(0)); + int typeId = gen->GetArgTypeId(0); + CScriptHandle *self = reinterpret_cast(gen->GetObject()); + self->Cast(ref, typeId); +} + +void CScriptHandle_Assign_Generic(asIScriptGeneric *gen) +{ + CScriptHandle *other = reinterpret_cast(gen->GetArgAddress(0)); + CScriptHandle *self = reinterpret_cast(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(gen->GetObject()); + self->Assign(ref, typeId); + gen->SetReturnAddress(self); +} + +void CScriptHandle_Equals_Generic(asIScriptGeneric *gen) +{ + CScriptHandle *other = reinterpret_cast(gen->GetArgAddress(0)); + CScriptHandle *self = reinterpret_cast(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(gen->GetObject()); + gen->SetReturnByte(self->Equals(ref, typeId)); +} + +void CScriptHandle_EnumReferences_Generic(asIScriptGeneric *gen) +{ + CScriptHandle *self = reinterpret_cast(gen->GetObject()); + self->EnumReferences(gen->GetEngine()); +} + +void CScriptHandle_ReleaseReferences_Generic(asIScriptGeneric *gen) +{ + CScriptHandle *self = reinterpret_cast(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 diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API/EditorEngine_Environment.h b/DeerStudio/src/DeerStudio/EditorEngine/API/EditorEngine_Environment.h index e260116..ee4e72e 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API/EditorEngine_Environment.h +++ b/DeerStudio/src/DeerStudio/EditorEngine/API/EditorEngine_Environment.h @@ -1,16 +1,24 @@ #pragma once #include +#include 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); } } \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API/EditorEngine_Functions.h b/DeerStudio/src/DeerStudio/EditorEngine/API/EditorEngine_Functions.h index ce2a234..96271e6 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API/EditorEngine_Functions.h +++ b/DeerStudio/src/DeerStudio/EditorEngine/API/EditorEngine_Functions.h @@ -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 class asSMessageInfo; diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API/EditorEngine_TreeNode.h b/DeerStudio/src/DeerStudio/EditorEngine/API/EditorEngine_TreeNode.h index 2eeeccb..6843851 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API/EditorEngine_TreeNode.h +++ b/DeerStudio/src/DeerStudio/EditorEngine/API/EditorEngine_TreeNode.h @@ -2,10 +2,11 @@ #include 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&); } } \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/EditorEngine_Environment.cpp b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/EditorEngine_Environment.cpp index a3f67dc..3559c5b 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/EditorEngine_Environment.cpp +++ b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/EditorEngine_Environment.cpp @@ -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() + .childCount; + } + + EntityStruct EntityStruct::getChild(int i) { + RelationshipComponent& rc = Project::m_scene + .getMainEnviroment() + .getEntity(entityId) + .getComponent(); + + 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() + .tag; + } } } \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/EditorEngine_TreeNode.cpp b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/EditorEngine_TreeNode.cpp index 8cc5b6f..3d86ffe 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/EditorEngine_TreeNode.cpp +++ b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/EditorEngine_TreeNode.cpp @@ -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(); } } diff --git a/DeerStudio/src/DeerStudio/EditorEngine/EditorEngine_RegisterFunctions.cpp b/DeerStudio/src/DeerStudio/EditorEngine/EditorEngine_RegisterFunctions.cpp index 3e40754..93414df 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/EditorEngine_RegisterFunctions.cpp +++ b/DeerStudio/src/DeerStudio/EditorEngine/EditorEngine_RegisterFunctions.cpp @@ -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 + )); } } \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/EditorEngine/EditorEngine_RegisterStructs.cpp b/DeerStudio/src/DeerStudio/EditorEngine/EditorEngine_RegisterStructs.cpp index 4d0bb5d..e809469 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/EditorEngine_RegisterStructs.cpp +++ b/DeerStudio/src/DeerStudio/EditorEngine/EditorEngine_RegisterStructs.cpp @@ -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())); - + asOBJ_VALUE | asOBJ_POD | asGetTypeTraits() | 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(); } } } \ No newline at end of file diff --git a/roe/editor/tree_pannel/tree_pannel.as b/roe/editor/tree_pannel/tree_pannel.as index 3e5e6ed..6394105 100644 --- a/roe/editor/tree_pannel/tree_pannel.as +++ b/roe/editor/tree_pannel/tree_pannel.as @@ -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)); + } + + } } -} \ No newline at end of file +} diff --git a/roe/imgui.ini b/roe/imgui.ini index 114e719..0b63ae9 100644 --- a/roe/imgui.ini +++ b/roe/imgui.ini @@ -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