451 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			451 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #ifndef HX_OBJECT_H
 | ||
|  | #define HX_OBJECT_H
 | ||
|  | 
 | ||
|  | #ifndef HXCPP_H
 | ||
|  | #error "Please include hxcpp.h, not hx/Object.h"
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if defined(KORE_LINUX) && __cplusplus < 201103L
 | ||
|  | #include <math.h>
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | // --- Constants -------------------------------------------------------
 | ||
|  | 
 | ||
|  | // These values are returned from the "__GetType" function
 | ||
|  | enum hxObjectType | ||
|  | { | ||
|  |    vtUnknown = -1, | ||
|  |    vtInt = 0xff, | ||
|  |    vtNull = 0, | ||
|  |    vtFloat = 1, | ||
|  |    vtBool = 2, | ||
|  |    vtString = 3, | ||
|  |    vtObject = 4, | ||
|  |    vtArray = 5, | ||
|  |    vtFunction = 6, | ||
|  |    vtEnum, | ||
|  |    vtClass, | ||
|  |    vtInt64, | ||
|  |    vtAbstractBase = 0x100, | ||
|  | }; | ||
|  | 
 | ||
|  | 
 | ||
|  | namespace hx | ||
|  | { | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | class FieldRef; | ||
|  | class IndexRef; | ||
|  | typedef Array<Dynamic> DynamicArray; | ||
|  | HXCPP_EXTERN_CLASS_ATTRIBUTES null BadCast(); | ||
|  | 
 | ||
|  | #ifdef HXCPP_SCRIPTABLE
 | ||
|  | 
 | ||
|  | // CPPIA_CALL = fastcall on x86(32), nothing otherwise
 | ||
|  | #if (HXCPP_API_LEVEL >= 331)
 | ||
|  |    #if (defined(_WIN32) && !defined(_M_X64) && !defined(__x86_64__) && !defined(_ARM_) ) || \
 | ||
|  |       defined(HXCPP_X86) || defined(__i386__) || defined(__i386) || \ | ||
|  |         (!defined(_WIN32) && !defined(_ARM_) && !defined(__arm__) && !defined(__x86_64__) ) | ||
|  | 
 | ||
|  |       #if defined(__GNUC__) && !defined(__APPLE__) && !defined(EMSCRIPTEN)
 | ||
|  |          #define CPPIA_CALL __attribute__ ((fastcall))
 | ||
|  |       #elif defined(_MSC_VER)
 | ||
|  |          #define CPPIA_CALL __fastcall
 | ||
|  |       #endif
 | ||
|  |    #endif
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef CPPIA_CALL
 | ||
|  |    #define CPPIA_CALL
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | 
 | ||
|  | typedef void (CPPIA_CALL *StackExecute)(struct StackContext *ctx); | ||
|  | struct ScriptFunction | ||
|  | { | ||
|  |    ScriptFunction(StackExecute inExe=0,const char *inSig=0) | ||
|  |       : execute(inExe), signature(inSig) { } | ||
|  |    StackExecute execute; | ||
|  |    const char   *signature; | ||
|  | }; | ||
|  | struct ScriptCallable; | ||
|  | 
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | enum NewObjectType | ||
|  | { | ||
|  |    NewObjAlloc, | ||
|  |    NewObjContainer, | ||
|  |    NewObjConst, | ||
|  | }; | ||
|  | 
 | ||
|  | enum | ||
|  | { | ||
|  |    clsIdDynamic = 1, | ||
|  |    clsIdClass, | ||
|  |    clsIdInt, | ||
|  |    clsIdInt64, | ||
|  |    clsIdFloat, | ||
|  |    clsIdBool, | ||
|  |    clsIdString, | ||
|  |    clsIdMath, | ||
|  |    clsIdEnum, | ||
|  |    clsIdClosure, | ||
|  |    clsIdVirtualArray, | ||
|  |    clsIdArrayIterator, | ||
|  |    clsIdArrayBase, | ||
|  |    clsIdArrayByte, | ||
|  |    clsIdArrayShort, | ||
|  |    clsIdArrayInt, | ||
|  |    clsIdArrayBool, | ||
|  |    clsIdArrayFloat32, | ||
|  |    clsIdArrayFloat64, | ||
|  |    clsIdArrayString, | ||
|  |    clsIdArrayInt64, | ||
|  |    clsIdArrayObject, | ||
|  |    clsIdAbstract, | ||
|  |    clsIdHash, | ||
|  |    clsIdWeakRef, | ||
|  |    clsIdExternalPrimitive, | ||
|  |    clsIdPointer, | ||
|  |    clsIdStruct, | ||
|  |    clsIdCMember0, | ||
|  |    clsIdCMember1, | ||
|  |    clsIdCMember2, | ||
|  |    clsIdCMember3, | ||
|  |    clsIdCMember4, | ||
|  |    clsIdCMember5, | ||
|  |    clsIdCMemberVar, | ||
|  |    clsIdCStatic0, | ||
|  |    clsIdCStatic1, | ||
|  |    clsIdCStatic2, | ||
|  |    clsIdCStatic3, | ||
|  |    clsIdCStatic4, | ||
|  |    clsIdCStatic5, | ||
|  |    clsIdCStatic6, | ||
|  |    clsIdCStaticVar, | ||
|  |    clsIdMutex, | ||
|  |    clsIdSemaphore, | ||
|  |    clsIdCondition, | ||
|  |    clsIdLock, | ||
|  |    clsIdDeque, | ||
|  |    clsIdThreadInfo, | ||
|  |    clsIdPcreData, | ||
|  |    clsIdFio, | ||
|  |    clsIdProcess, | ||
|  |    clsIdSocket, | ||
|  |    clsIdRandom, | ||
|  |    clsIdPollData, | ||
|  |    clsIdSqlite, | ||
|  |    clsIdMysql, | ||
|  |    clsIdMysqlResult, | ||
|  |    clsIdSsl, | ||
|  |    clsIdSslCert, | ||
|  |    clsIdSslConf, | ||
|  |    clsIdSslKey, | ||
|  |    clsIdZLib, | ||
|  | 
 | ||
|  | }; | ||
|  | 
 | ||
|  | 
 | ||
|  | // --- hx::Object ------------------------------------------------------------
 | ||
|  | //
 | ||
|  | // Base for all hxcpp objects.
 | ||
|  | // This contains the virtual functions required by the core to provide
 | ||
|  | //  a generic interface to the specific classes.
 | ||
|  | //
 | ||
|  | // Hxcpp classes inherit from this.
 | ||
|  | //
 | ||
|  | class HXCPP_EXTERN_CLASS_ATTRIBUTES Object | ||
|  | { | ||
|  | public: | ||
|  |    enum { _hx_ClassId = hx::clsIdDynamic }; | ||
|  | 
 | ||
|  | 
 | ||
|  |    inline void *operator new( size_t inSize, bool inContainer=true, const char *inName=0 ) | ||
|  |    { | ||
|  |       #ifdef HX_USE_INLINE_IMMIX_OPERATOR_NEW
 | ||
|  |          ImmixAllocator *alloc =  HX_CTX_GET; | ||
|  | 
 | ||
|  |          #ifdef HXCPP_DEBUG
 | ||
|  |          if (!alloc) | ||
|  |             BadImmixAlloc(); | ||
|  |          #endif
 | ||
|  | 
 | ||
|  |          return ImmixAllocator::alloc(alloc, inSize, inContainer, inName); | ||
|  | 
 | ||
|  |       #else // Not HX_USE_INLINE_IMMIX_OPERATOR_NEW ...
 | ||
|  | 
 | ||
|  |          void *result = hx::InternalNew(inSize,inContainer); | ||
|  | 
 | ||
|  |          #ifdef HXCPP_TELEMETRY
 | ||
|  |             __hxt_gc_new(result, inSize, inName); | ||
|  |          #endif
 | ||
|  |          return result; | ||
|  |       #endif
 | ||
|  |    } | ||
|  | 
 | ||
|  |    inline void *operator new( size_t inSize, hx::NewObjectType inType,  const char *inName=0 ) | ||
|  |    { | ||
|  |       if (inType==NewObjConst) | ||
|  |          return InternalCreateConstBuffer(0,(int)inSize); | ||
|  |       return operator new(inSize, inType==NewObjContainer, inName); | ||
|  |    } | ||
|  | 
 | ||
|  |    void operator delete( void *, bool) { } | ||
|  |    void operator delete( void *, bool, const char * ) { } | ||
|  |    void operator delete( void *, int ) { } | ||
|  |    void operator delete( void *, hx::NewObjectType) { } | ||
|  |    void operator delete( void *, hx::NewObjectType, const char * ) { } | ||
|  | 
 | ||
|  |    #if (HXCPP_API_LEVEL>=332)
 | ||
|  |    virtual bool _hx_isInstanceOf(int inClassId); | ||
|  |    #endif
 | ||
|  | 
 | ||
|  |    //virtual void *__root();
 | ||
|  |    virtual void __Mark(hx::MarkContext *__inCtx) { } | ||
|  |    #ifdef HXCPP_VISIT_ALLOCS
 | ||
|  |    virtual void __Visit(hx::VisitContext *__inCtx) { } | ||
|  |    #endif
 | ||
|  | 
 | ||
|  |    // helpers...
 | ||
|  |    inline bool __IsArray() const { return __GetType()==vtArray; } | ||
|  | 
 | ||
|  |    virtual int __GetType() const { return vtClass; } | ||
|  |    virtual void *__GetHandle() const { return 0; } | ||
|  | 
 | ||
|  | 
 | ||
|  |    virtual hx::FieldRef __FieldRef(const String &inString); | ||
|  | 
 | ||
|  |    virtual String __ToString() const; | ||
|  | 
 | ||
|  |    virtual int __ToInt() const { return 0; } | ||
|  | #if defined(KORE_LINUX) && __cplusplus < 201103L
 | ||
|  |    virtual double __ToDouble() const { return NAN; } | ||
|  | #else
 | ||
|  |    virtual double __ToDouble() const { return std::numeric_limits<double>::quiet_NaN(); } | ||
|  | #endif
 | ||
|  |    virtual cpp::Int64 __ToInt64() const { return (cpp::Int64)(0); } | ||
|  |    virtual const char * __CStr() const; | ||
|  |    virtual String toString(); | ||
|  |    virtual bool __HasField(const String &inString); | ||
|  |    virtual hx::Val __Field(const String &inString, hx::PropertyAccess inCallProp); | ||
|  | 
 | ||
|  |    #if (HXCPP_API_LEVEL <= 330)
 | ||
|  |    virtual bool __Is(hx::Object *inClass) const { return true; } | ||
|  |    virtual hx::Object *__GetRealObject() { return this; } | ||
|  |    bool __Is(Dynamic inClass ) const; | ||
|  |    #endif
 | ||
|  | 
 | ||
|  |    #if (HXCPP_API_LEVEL >= 330)
 | ||
|  |    // Non-virtual
 | ||
|  |    Dynamic __IField(int inFieldID); | ||
|  |    double __INumField(int inFieldID); | ||
|  |    virtual void *_hx_getInterface(int inId); | ||
|  |    #else
 | ||
|  |    virtual hx::Object *__ToInterface(const hx::type_info &inInterface) { return 0; } | ||
|  |    virtual Dynamic __IField(int inFieldID); | ||
|  |    virtual double __INumField(int inFieldID); | ||
|  | 
 | ||
|  |    // These have been moved to EnumBase
 | ||
|  |    virtual DynamicArray __EnumParams(); | ||
|  |    virtual String __Tag() const; | ||
|  |    virtual int __Index() const; | ||
|  |    virtual void __SetSize(int inLen) { } | ||
|  |    #endif
 | ||
|  | 
 | ||
|  |    virtual hx::Val __SetField(const String &inField,const hx::Val &inValue, hx::PropertyAccess inCallProp); | ||
|  | 
 | ||
|  |    virtual void  __SetThis(Dynamic inThis); | ||
|  |    virtual Dynamic __Run(const Array<Dynamic> &inArgs); | ||
|  |    virtual Dynamic *__GetFieldMap(); | ||
|  |    virtual void __GetFields(Array<String> &outFields); | ||
|  |    virtual hx::Class __GetClass() const; | ||
|  | 
 | ||
|  |    virtual int __Compare(const hx::Object *inRHS) const; | ||
|  | 
 | ||
|  |    virtual int __length() const { return 0; } | ||
|  |    virtual Dynamic __GetItem(int inIndex) const; | ||
|  |    virtual Dynamic __SetItem(int inIndex,Dynamic inValue); | ||
|  | 
 | ||
|  | 
 | ||
|  |    typedef const Dynamic &D; | ||
|  |    virtual Dynamic __run(); | ||
|  |    virtual Dynamic __run(D a); | ||
|  |    virtual Dynamic __run(D a,D b); | ||
|  |    virtual Dynamic __run(D a,D b,D c); | ||
|  |    virtual Dynamic __run(D a,D b,D c,D d); | ||
|  |    virtual Dynamic __run(D a,D b,D c,D d,D e); | ||
|  | 
 | ||
|  |    virtual int __ArgCount() const { return -1; } | ||
|  | 
 | ||
|  |    #ifdef HXCPP_SCRIPTABLE
 | ||
|  |    virtual void **__GetScriptVTable() { return 0; } | ||
|  |    virtual hx::ScriptCallable *__GetScriptCallable() { return 0; } | ||
|  |    static hx::ScriptFunction __script_construct; | ||
|  |    #endif
 | ||
|  | 
 | ||
|  |    #if (HXCPP_API_LEVEL>=331)
 | ||
|  |    inline bool __compare( hx::Object *inRHS ) { return this!=inRHS; } | ||
|  |    #else
 | ||
|  |    inline bool __compare( hx::Object *inRHS ) | ||
|  |       { return __GetRealObject()!=inRHS->__GetRealObject(); } | ||
|  |    #endif
 | ||
|  | 
 | ||
|  |    static hx::Class &__SGetClass(); | ||
|  |    static void __boot(); | ||
|  | }; | ||
|  | 
 | ||
|  | // --- hx::ObjectPtr ---------------------------------------------------------------
 | ||
|  | //
 | ||
|  | // This class simply provides syntax so that pointers can be written as objects,
 | ||
|  | //  and overloaded operators can be used
 | ||
|  | 
 | ||
|  | template<typename OBJ_> | ||
|  | class ObjectPtr | ||
|  | { | ||
|  | protected: | ||
|  |    inline bool SetPtr(OBJ_ *inPtr) | ||
|  |    { | ||
|  |       mPtr = inPtr; | ||
|  |       return true; | ||
|  |    } | ||
|  |    inline bool SetPtr(...) { return false; } | ||
|  | 
 | ||
|  |    inline void CastPtr(hx::Object *inPtr,bool inThrowOnInvalid) | ||
|  |    { | ||
|  |       if (inPtr) | ||
|  |       { | ||
|  |          #if (HXCPP_API_LEVEL>=332)
 | ||
|  |             mPtr = inPtr->_hx_isInstanceOf(OBJ_::_hx_ClassId) ? reinterpret_cast<OBJ_ *>(inPtr) : 0; | ||
|  |          #elif (HXCPP_API_LEVEL>=331)
 | ||
|  |             mPtr = dynamic_cast<OBJ_ *>(inPtr); | ||
|  |          #else
 | ||
|  |             mPtr = dynamic_cast<OBJ_ *>(inPtr->__GetRealObject()); | ||
|  |             #if (HXCPP_API_LEVEL < 330)
 | ||
|  |             if (!mPtr) | ||
|  |                mPtr = (Ptr)inPtr->__ToInterface(typeid(Obj)); | ||
|  |             #endif
 | ||
|  |          #endif
 | ||
|  |          if (inThrowOnInvalid && !mPtr) | ||
|  |             ::hx::BadCast(); | ||
|  |       } | ||
|  |       else | ||
|  |          mPtr = 0; | ||
|  |    } | ||
|  | 
 | ||
|  | public: | ||
|  |    typedef OBJ_ Obj; | ||
|  |    typedef OBJ_ *Ptr; | ||
|  | 
 | ||
|  |    inline ObjectPtr() : mPtr(0) { } | ||
|  |    inline ObjectPtr(OBJ_ *inObj) : mPtr(inObj) { } | ||
|  |    inline ObjectPtr(const null &inNull) : mPtr(0) { } | ||
|  |    inline ObjectPtr(const ObjectPtr<OBJ_> &inOther) : mPtr( inOther.mPtr ) {  } | ||
|  |    template<typename T> | ||
|  |    inline ObjectPtr(const hx::Native<T> &inNative) : mPtr( dynamic_cast<T>(inNative.ptr) ) {  } | ||
|  | 
 | ||
|  |    template<typename SOURCE_> | ||
|  |    inline ObjectPtr(const ObjectPtr<SOURCE_> &inObjectPtr) | ||
|  |    { | ||
|  |       if (!SetPtr(inObjectPtr.mPtr)) | ||
|  |          CastPtr(inObjectPtr.mPtr,false); | ||
|  |    } | ||
|  | 
 | ||
|  | 
 | ||
|  |    inline ObjectPtr(const ::cpp::Variant &inVariant) | ||
|  |    { | ||
|  |       hx::Object *object = inVariant.asObject(); | ||
|  |       if (!SetPtr(object)) | ||
|  |          CastPtr(object,false); | ||
|  |    } | ||
|  | 
 | ||
|  |    template<typename SOURCE_> | ||
|  |    inline ObjectPtr(const SOURCE_ *inPtr,bool inCheckCast=true) | ||
|  |    { | ||
|  |       if (!SetPtr(const_cast<SOURCE_ *>(inPtr))) | ||
|  |          CastPtr(const_cast<SOURCE_ *>(inPtr),inCheckCast); | ||
|  |    } | ||
|  | 
 | ||
|  |    inline ObjectPtr &operator=(const null &inNull) { mPtr = 0; return *this; } | ||
|  |    inline ObjectPtr &operator=(Ptr inRHS) { mPtr = inRHS; return *this; } | ||
|  |    inline ObjectPtr &operator=(const ObjectPtr &inRHS) { mPtr = inRHS.mPtr; return *this; } | ||
|  |    template<typename InterfaceImpl> | ||
|  |    inline ObjectPtr &operator=(InterfaceImpl *inRHS) | ||
|  |    { | ||
|  |       mPtr = inRHS->operator Ptr(); | ||
|  |       return *this; | ||
|  |    } | ||
|  | 
 | ||
|  |    inline OBJ_ *GetPtr() const { return mPtr; } | ||
|  |    inline OBJ_ *operator->() | ||
|  |    { | ||
|  |       #ifdef HXCPP_CHECK_POINTER
 | ||
|  |       if (!mPtr) NullReference("Object", true); | ||
|  |       // The handler might have fixed up the null value
 | ||
|  |       if (!mPtr) NullReference("Object", false); | ||
|  |       #ifdef HXCPP_GC_CHECK_POINTER
 | ||
|  |          GCCheckPointer(mPtr); | ||
|  |       #endif
 | ||
|  |       #endif
 | ||
|  |       return mPtr; | ||
|  |    } | ||
|  |    inline const OBJ_ *operator->() const | ||
|  |    { | ||
|  |       #ifdef HXCPP_CHECK_POINTER
 | ||
|  |       if (!mPtr) NullReference("Object", true); | ||
|  |       // The handler might have fixed up the null value
 | ||
|  |       if (!mPtr) NullReference("Object", false); | ||
|  |       #ifdef HXCPP_GC_CHECK_POINTER
 | ||
|  |          GCCheckPointer(mPtr); | ||
|  |       #endif
 | ||
|  |       #endif
 | ||
|  |       return mPtr; | ||
|  |    } | ||
|  | 
 | ||
|  |    template<typename T> | ||
|  |    inline bool operator==(const T &inTRHS) const | ||
|  |    { | ||
|  |       ObjectPtr inRHS(inTRHS.mPtr,false); | ||
|  |       if (mPtr==inRHS.mPtr) return true; | ||
|  |       if (!mPtr || !inRHS.mPtr) return false; | ||
|  |       return !mPtr->__compare(inRHS.mPtr); | ||
|  |    } | ||
|  |    inline bool operator==(const cpp::Variant &inRHS) const; | ||
|  |    inline bool operator!=(const cpp::Variant &inRHS) const; | ||
|  | 
 | ||
|  |    template<typename T> | ||
|  |    inline bool operator!=(const T &inTRHS) const | ||
|  |    { | ||
|  |       ObjectPtr inRHS(inTRHS.mPtr,false); | ||
|  |       if (mPtr==inRHS.mPtr) return false; | ||
|  |       if (!mPtr || !inRHS.mPtr) return true; | ||
|  |       return mPtr->__compare(inRHS.mPtr); | ||
|  |    } | ||
|  | 
 | ||
|  |    template<typename T> | ||
|  |    operator hx::Native<T> () { return hx::Native<T>( mPtr ); } | ||
|  | 
 | ||
|  |    inline bool operator==(const null &inRHS) const { return mPtr==0; } | ||
|  |    inline bool operator!=(const null &inRHS) const { return mPtr!=0; } | ||
|  | 
 | ||
|  |    //inline bool operator==(const Dynamic &inRHS) const { return inRHS==*this; }
 | ||
|  |    //inline bool operator!=(const Dynamic &inRHS) const { return inRHS!=*this; }
 | ||
|  | 
 | ||
|  | 
 | ||
|  |    // This is defined in the "FieldRef" class...
 | ||
|  |    inline class hx::FieldRef FieldRef(const String &inString); | ||
|  |    inline class hx::IndexRef IndexRef(int inString); | ||
|  |    inline static hx::Class &__SGetClass() { return OBJ_::__SGetClass(); } | ||
|  | 
 | ||
|  |    OBJ_ *mPtr; | ||
|  | }; | ||
|  | 
 | ||
|  | 
 | ||
|  | } // end namespace hx
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #endif
 |