290 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			290 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #ifndef INCLUDED_HX_SCRIPTABLE
 | |
| #define INCLUDED_HX_SCRIPTABLE
 | |
| 
 | |
| #include <typeinfo>
 | |
| #ifdef __clang__
 | |
| #pragma clang diagnostic ignored "-Winvalid-offsetof"
 | |
| #endif
 | |
| 
 | |
| 
 | |
| namespace hx
 | |
| {
 | |
| 
 | |
| extern bool gEnableJit;
 | |
| inline void EnableJit(bool inEnable) { gEnableJit = inEnable; }
 | |
| 
 | |
| #define HXCPP_CPPIA_SUPER_ARG(x) , (x)
 | |
| 
 | |
| struct ScriptNamedFunction : public ScriptFunction
 | |
| {
 | |
|    ScriptNamedFunction(const ScriptFunction &s) : ScriptFunction(s), name(0), isStatic(false), superExecute(0) { }
 | |
| 
 | |
|    ScriptNamedFunction(const char *inName=0,StackExecute inExe=0,const char *inSig=0, bool inIsStatic=false, StackExecute superExecute=0)
 | |
|       : ScriptFunction(inExe, inSig), name(inName), isStatic(inIsStatic), superExecute(superExecute)  { }
 | |
| 
 | |
|    const char *name;
 | |
|    bool isStatic;
 | |
|    StackExecute superExecute;
 | |
| };
 | |
| 
 | |
| 
 | |
| inline void SetFloatAligned(void *inPtr, const Float &inValue)
 | |
| {
 | |
|    #ifdef HXCPP_ALIGN_FLOAT
 | |
|    int *dest = (int *)inPtr;
 | |
|    const int *src = (const int *)&inValue;
 | |
|    dest[1] = src[1];
 | |
|    #else
 | |
|    *(Float *)inPtr = inValue;
 | |
|    #endif
 | |
| }
 | |
| 
 | |
| 
 | |
| inline Float GetFloatAligned(const void *inPtr)
 | |
| {
 | |
|    #ifdef HXCPP_ALIGN_FLOAT
 | |
|    Float result;
 | |
|    int *dest = (int *)&result;
 | |
|    const int *src = (const int *)inPtr;
 | |
|    dest[0] = src[0];
 | |
|    dest[1] = src[1];
 | |
|    return result;
 | |
|    #else
 | |
|    return *(Float *)inPtr;
 | |
|    #endif
 | |
| }
 | |
| 
 | |
| 
 | |
| inline void StackContext::pushFloat(Float f)
 | |
| {
 | |
|    SetFloatAligned(pointer, f);
 | |
|    pointer += sizeof(Float);
 | |
| }
 | |
| inline void StackContext::pushString(const String &s)
 | |
| {
 | |
|    *(String *)pointer = s;
 | |
|    pointer += sizeof(String);
 | |
| }
 | |
| 
 | |
| inline void StackContext::pushObject(Dynamic d)
 | |
| {
 | |
|    *(hx::Object **)pointer = d.mPtr;
 | |
|    pointer += sizeof(hx::Object *);
 | |
| }
 | |
| 
 | |
| inline void StackContext::returnFloat(Float f)
 | |
| {
 | |
|    SetFloatAligned(frame, f);
 | |
| }
 | |
| inline void StackContext::returnString(const String &s)
 | |
| {
 | |
|    *(String *)frame = s;
 | |
| }
 | |
| inline void StackContext::returnObject(Dynamic d)
 | |
| {
 | |
|    *(hx::Object **)frame = d.mPtr;
 | |
| }
 | |
| 
 | |
| inline hx::Object *StackContext::getThis(bool inCheckPtr)
 | |
| {
 | |
|    #ifdef HXCPP_CHECK_POINTER
 | |
|       if (inCheckPtr)
 | |
|       {
 | |
|          if (!*(hx::Object **)frame) NullReference("This", false);
 | |
|          #ifdef HXCPP_GC_CHECK_POINTER
 | |
|          GCCheckPointer(*(hx::Object **)frame);
 | |
|          #endif
 | |
|       }
 | |
|    #endif
 | |
|    return *(hx::Object **)frame;
 | |
| }
 | |
| 
 | |
| 
 | |
| inline Float StackContext::getFloat(int inPos)
 | |
| {
 | |
|    return GetFloatAligned(frame+inPos);
 | |
| }
 | |
| inline String StackContext::getString(int inPos)
 | |
| {
 | |
|    return *(String *)(frame+inPos);
 | |
| }
 | |
| inline Dynamic StackContext::getObject(int inPos)
 | |
| {
 | |
|    return *(hx::Object **)(frame+inPos);
 | |
| }
 | |
| 
 | |
| 
 | |
| enum SignatureChar
 | |
| {
 | |
|    sigVoid = 'v',
 | |
|    sigBool = 'b',
 | |
|    sigInt = 'i',
 | |
|    sigFloat = 'f',
 | |
|    sigString = 's',
 | |
|    sigObject = 'o',
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| struct AutoStack
 | |
| {
 | |
|    CppiaCtx *ctx;
 | |
|    unsigned char *pointer;
 | |
|    unsigned char *frame;
 | |
| 
 | |
|    AutoStack(CppiaCtx *inCtx) : ctx(inCtx)
 | |
|    {
 | |
|       frame = ctx->frame;
 | |
|       pointer = ctx->pointer;
 | |
|       ctx->frame = pointer;
 | |
|    }
 | |
|    AutoStack(CppiaCtx *inCtx,unsigned char *inPointer) : ctx(inCtx)
 | |
|    {
 | |
|       frame = ctx->frame;
 | |
|       pointer = inPointer;
 | |
|       ctx->frame = pointer;
 | |
|    }
 | |
| 
 | |
|    ~AutoStack()
 | |
|    {
 | |
|       ctx->pointer = pointer;
 | |
|       ctx->frame = frame;
 | |
|    }
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| typedef hx::Object * (*ScriptableClassFactory)(void **inVTable,int inDataSize);
 | |
| typedef hx::Object * (*ScriptableInterfaceFactory)(void **inVTable,::hx::Object *);
 | |
| 
 | |
| void ScriptableRegisterClass( String inName, int inBaseSize, ScriptNamedFunction *inFunctions, ScriptableClassFactory inFactory, ScriptFunction inConstruct);
 | |
| 
 | |
| 
 | |
| #if (HXCPP_API_LEVEL >= 330)
 | |
| void ScriptableRegisterInterface( String inName, ScriptNamedFunction *inFunctions, void *inInterfacePointers);
 | |
| void ScriptableRegisterNameSlots(const char *inNames[], int inLength);
 | |
| 
 | |
| #else
 | |
| void ScriptableRegisterInterface( String inName, ScriptNamedFunction *inFunctions,const hx::type_info *inType, ScriptableInterfaceFactory inFactory);
 | |
| #endif
 | |
| 
 | |
| ::String ScriptableToString(void *);
 | |
| hx::Class ScriptableGetClass(void *);
 | |
| int ScriptableGetType(void *);
 | |
| void ScriptableMark(void *, hx::Object *, HX_MARK_PARAMS);
 | |
| void ScriptableVisit(void *, hx::Object *, HX_VISIT_PARAMS);
 | |
| bool ScriptableField(hx::Object *, const ::String &,hx::PropertyAccess inCallProp,Dynamic &outResult);
 | |
| bool ScriptableField(hx::Object *, int inName,hx::PropertyAccess inCallProp,Float &outResult);
 | |
| bool ScriptableField(hx::Object *, int inName,hx::PropertyAccess inCallProp,Dynamic &outResult);
 | |
| void ScriptableGetFields(hx::Object *inObject, Array< ::String> &outFields);
 | |
| bool ScriptableSetField(hx::Object *, const ::String &, Dynamic inValue,hx::PropertyAccess inCallProp, Dynamic &outValue);
 | |
| 
 | |
| 
 | |
| class CppiaLoadedModule_obj : public ::hx::Object
 | |
| {
 | |
| public:
 | |
|    virtual void run() = 0;
 | |
|    virtual void boot() = 0;
 | |
|    virtual ::hx::Class resolveClass( ::String inName) = 0;
 | |
| };
 | |
| typedef ::hx::ObjectPtr<CppiaLoadedModule_obj> CppiaLoadedModule;
 | |
| 
 | |
| 
 | |
| 
 | |
| } // End namespace hx
 | |
| 
 | |
| void __scriptable_load_neko(String inName);
 | |
| void __scriptable_load_cppia(String inCode);
 | |
| ::hx::CppiaLoadedModule __scriptable_cppia_from_string(String inCode);
 | |
| ::hx::CppiaLoadedModule __scriptable_cppia_from_data(Array<unsigned char> inBytes);
 | |
| void __scriptable_load_neko_bytes(Array<unsigned char> inBytes);
 | |
| void __scriptable_load_abc(Array<unsigned char> inBytes);
 | |
| 
 | |
| #if (HXCPP_API_LEVEL >= 330)
 | |
| 
 | |
| #define HX_SCRIPTABLE_REGISTER_INTERFACE(name,class) \
 | |
|     hx::ScriptableRegisterInterface( HX_CSTRING(name), __scriptableFunctions, & class##_scriptable )
 | |
| 
 | |
| #else
 | |
| 
 | |
| #define HX_SCRIPTABLE_REGISTER_INTERFACE(name,class) \
 | |
|     hx::ScriptableRegisterInterface( HX_CSTRING(name), __scriptableFunctions, &typeid(class), class##__scriptable::__script_create )
 | |
| 
 | |
| #endif
 | |
| 
 | |
| #define HX_SCRIPTABLE_REGISTER_CLASS(name,class) \
 | |
|    hx::ScriptableRegisterClass( HX_CSTRING(name), (int)offsetof(class##__scriptable,__scriptVTable) + sizeof(void *), __scriptableFunctions, class##__scriptable::__script_create, class##__scriptable::__script_construct )
 | |
| 
 | |
| 
 | |
| #ifdef HXCPP_VISIT_ALLOCS
 | |
| #define SCRIPTABLE_VISIT_FUNCTION \
 | |
| void __Visit(HX_VISIT_PARAMS) { super::__Visit(HX_VISIT_ARG); hx::ScriptableVisit(__scriptVTable[-1],this,HX_VISIT_ARG); }
 | |
| #else
 | |
| #define SCRIPTABLE_VISIT_FUNCTION
 | |
| #endif
 | |
| 
 | |
| 
 | |
| #define HX_DEFINE_SCRIPTABLE(ARG_LIST) \
 | |
|    inline void *operator new( size_t inSize, int inExtraDataSize ) \
 | |
|    { \
 | |
|       return hx::InternalNew(inSize + inExtraDataSize,true); \
 | |
|    } \
 | |
|    inline void operator delete(void *,int) {} \
 | |
|    public: \
 | |
|    void **__scriptVTable; \
 | |
|    static hx::Object *__script_create(void **inVTable, int inExtra) { \
 | |
|     __ME *result = new (inExtra) __ME(); \
 | |
|     result->__scriptVTable = inVTable; \
 | |
|    return result; } \
 | |
|    void ** __GetScriptVTable() { return __scriptVTable; } \
 | |
|    ::String toString() {  if (__scriptVTable[0] ) \
 | |
|      { hx::CppiaCtx *ctx = hx::CppiaCtx::getCurrent(); hx::AutoStack a(ctx); ctx->pushObject(this); return ctx->runString(__scriptVTable[0]); } \
 | |
|       else return __superString::toString(); } \
 | |
|    ::String __ToString() const { return hx::ScriptableToString(__scriptVTable[-1]); } \
 | |
|    hx::Class __GetClass() const { return hx::ScriptableGetClass(__scriptVTable[-1]); } \
 | |
|    int __GetType() const { return hx::ScriptableGetType(__scriptVTable[-1]); } \
 | |
|    void __Mark(HX_MARK_PARAMS) { super::__Mark(HX_MARK_ARG); hx::ScriptableMark(__scriptVTable[-1],this,HX_MARK_ARG); } \
 | |
|    SCRIPTABLE_VISIT_FUNCTION
 | |
| 
 | |
| 
 | |
| 
 | |
| #define HX_DEFINE_SCRIPTABLE_INTERFACE \
 | |
|    void **__scriptVTable; \
 | |
|    Dynamic mDelegate; \
 | |
|    hx::Object *__GetRealObject() { return mDelegate.mPtr; } \
 | |
|    SCRIPTABLE_VISIT_FUNCTION \
 | |
|    void ** __GetScriptVTable() { return __scriptVTable; } \
 | |
|    public: \
 | |
|    static hx::Object *__script_create(void **inVTable,hx::Object *inDelegate) { \
 | |
|     __ME *result = new __ME(); \
 | |
|     result->__scriptVTable = inVTable; \
 | |
|     result->mDelegate = inDelegate; \
 | |
|     return result; }
 | |
| 
 | |
| 
 | |
| 
 | |
| #define HX_DEFINE_SCRIPTABLE_DYNAMIC \
 | |
|  \
 | |
| 	hx::Val __Field(const ::String &inName,hx::PropertyAccess inCallProp) \
 | |
|       { Dynamic result; if (hx::ScriptableField(this,inName,inCallProp,result)) return result; return super::__Field(inName,inCallProp); } \
 | |
| 	Float __INumField(int inFieldID) \
 | |
| 		{ Float result; if (hx::ScriptableField(this,inFieldID,hx::paccAlways,result)) return result; return super::__INumField(inFieldID); } \
 | |
| 	Dynamic __IField(int inFieldID) \
 | |
| 		{ Dynamic result; if (hx::ScriptableField(this,inFieldID,hx::paccAlways,result)) return result; return super::__IField(inFieldID); } \
 | |
|    hx::Val __SetField(const ::String &inName,const hx::Val &inValue,hx::PropertyAccess inCallProp) \
 | |
|    { \
 | |
|       Dynamic value; \
 | |
|       if (hx::ScriptableSetField(this, inName, inValue,inCallProp,value)) \
 | |
|          return value; \
 | |
| 		return super::__SetField(inName,inValue,inCallProp); \
 | |
|    } \
 | |
| 	void __GetFields(Array< ::String> &outFields) \
 | |
| 		{ super::__GetFields(outFields); hx::ScriptableGetFields(this,outFields); }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| #endif
 |