git » swiftpm » main » tree

[main] / Sources / c_snikket / iinclude / hx / Scriptable.h

#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);


void ScriptableRegisterInterface( String inName, ScriptNamedFunction *inFunctions, void *inInterfacePointers);
void ScriptableRegisterNameSlots(const char *inNames[], int inLength);

::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);

#define HX_SCRIPTABLE_REGISTER_INTERFACE(name,class) \
    hx::ScriptableRegisterInterface( HX_CSTRING(name), __scriptableFunctions, & class##_scriptable )

#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