2025-01-22 16:18:30 +01:00

376 lines
9.2 KiB
C++

#include <hxcpp.h>
#include <map>
#ifdef ANDROID
#include <android/log.h>
#endif
namespace hx
{
typedef std::map<String,Class> ClassMap;
static ClassMap *sClassMap = 0;
Class _hx_RegisterClass(const String &inClassName, CanCastFunc inCanCast,
String inStatics[], String inMembers[],
ConstructEmptyFunc inConstructEmpty, ConstructArgsFunc inConstructArgs,
Class *inSuperClass, ConstructEnumFunc inConstructEnum,
MarkFunc inMarkFunc
#ifdef HXCPP_VISIT_ALLOCS
,VisitFunc inVisitFunc
#endif
#ifdef HXCPP_SCRIPTABLE
,const hx::StorageInfo *inStorageInfo
,const hx::StaticInfo *inStaticInfo
#endif
)
{
if (sClassMap==0)
sClassMap = new ClassMap;
Class_obj *obj = new Class_obj(inClassName, inStatics, inMembers,
inConstructEmpty, inConstructArgs, inSuperClass,
inConstructEnum, inCanCast, inMarkFunc
#ifdef HXCPP_VISIT_ALLOCS
,inVisitFunc
#endif
#ifdef HXCPP_SCRIPTABLE
,inStorageInfo
,inStaticInfo
#endif
);
Class c(obj);
(*sClassMap)[inClassName] = c;
return c;
}
void _hx_RegisterClass(const String &inClassName, Class inClass)
{
if (sClassMap==0)
sClassMap = new ClassMap;
(*sClassMap)[inClassName] = inClass;
}
// -------- Class ---------------------------------------
Class_obj::Class_obj(const String &inClassName,String inStatics[], String inMembers[],
ConstructEmptyFunc inConstructEmpty, ConstructArgsFunc inConstructArgs,
Class *inSuperClass,ConstructEnumFunc inConstructEnum,
CanCastFunc inCanCast, MarkFunc inFunc
#ifdef HXCPP_VISIT_ALLOCS
,VisitFunc inVisitFunc
#endif
#ifdef HXCPP_SCRIPTABLE
,const hx::StorageInfo *inStorageInfo
,const hx::StaticInfo *inStaticInfo
#endif
)
{
mName = inClassName.makePermanent();
mSuper = inSuperClass;
mConstructEmpty = inConstructEmpty;
mConstructArgs = inConstructArgs;
mConstructEnum = inConstructEnum;
mMarkFunc = inFunc;
#ifdef HXCPP_VISIT_ALLOCS
mVisitFunc = inVisitFunc;
#endif
#ifdef HXCPP_SCRIPTABLE
mMemberStorageInfo = inStorageInfo;
mStaticStorageInfo = inStaticInfo;
#endif
mStatics = dupFunctions(inStatics);
mMembers = dupFunctions(inMembers);
mCanCast = inCanCast;
}
bool Class_obj::GetNoStaticField(const String &inString, Dynamic &outValue, hx::PropertyAccess inCallProp)
{
return false;
}
bool Class_obj::SetNoStaticField(const String &inString, Dynamic &ioValue, hx::PropertyAccess inCallProp)
{
return false;
}
::Array< ::String > Class_obj::dupFunctions(String inFuncs[])
{
if (!inFuncs)
return null();
int count = 0;
for(String *s = inFuncs; s->length; s++)
count++;
Array<String> result = Array_obj<String>::__newConstWrapper(&inFuncs[0],count);
return result;
}
void Class_obj::registerScriptable(bool inOverwrite)
{
if (!inOverwrite && sClassMap->find(mName)!=sClassMap->end())
return;
(*sClassMap)[ mName ] = this;
}
Class Class_obj::GetSuper()
{
if (!mSuper)
return null();
if (mSuper==&hx::Object::__SGetClass())
return null();
return *mSuper;
}
Class Class_obj__mClass;
Class Class_obj::__GetClass() const { return Class_obj__mClass; }
Class &Class_obj::__SGetClass() { return Class_obj__mClass; }
void Class_obj::__boot()
{
Static(Class_obj__mClass) = hx::_hx_RegisterClass(HX_CSTRING("Class"),TCanCast<Class_obj>,sNone,sNone, 0,0 , 0, 0 );
}
void Class_obj::MarkStatics(hx::MarkContext *__inCtx)
{
HX_MARK_MEMBER(__meta__);
if (mMarkFunc)
mMarkFunc(__inCtx);
}
#ifdef HXCPP_VISIT_ALLOCS
void Class_obj::VisitStatics(hx::VisitContext *__inCtx)
{
HX_VISIT_MEMBER(__meta__);
if (mVisitFunc)
mVisitFunc(__inCtx);
}
#endif
Class Class_obj::Resolve(String inName)
{
ClassMap::const_iterator i = sClassMap->find(inName);
if (i==sClassMap->end())
{
// Class class...
if (inName==HX_CSTRING("Enum"))
return Class_obj__mClass;
return null();
}
return i->second;
}
Dynamic Class_obj::ConstructEmpty()
{
return mConstructEmpty();
}
Dynamic Class_obj::ConstructArgs(DynamicArray inArgs)
{
return mConstructArgs(inArgs);
}
Dynamic Class_obj::ConstructEnum(String inName,DynamicArray inArgs)
{
if (mConstructEnum==0)
return null();
return mConstructEnum(inName,inArgs);
}
String Class_obj::__ToString() const { return mName; }
Array<String> Class_obj::GetInstanceFields()
{
Array<String> result = mSuper && (*mSuper).mPtr != this ? (*mSuper)->GetInstanceFields() : Array<String>(0,0);
if (mMembers.mPtr)
for(int m=0;m<mMembers->size();m++)
{
const String &mem = mMembers[m];
if (result->Find(mem)==-1)
result.Add(mem);
}
return result;
}
Array<String> Class_obj::GetClassFields()
{
Array<String> result = mStatics.mPtr ? mStatics->copy() : new Array_obj<String>(0,0);
if (__rtti__.raw_ptr())
result->push( HX_CSTRING("__rtti") );
return result;
}
bool Class_obj::__HasField(const String &inString)
{
if (__rtti__.raw_ptr() && inString==HX_CSTRING("__rtti"))
return true;
if (mStatics.mPtr)
for(int s=0;s<mStatics->size();s++)
if (mStatics[s]==inString)
return true;
return false;
}
hx::Val Class_obj::__Field(const String &inString, hx::PropertyAccess inCallProp)
{
if (inString==HX_CSTRING("__meta__"))
return __meta__;
#if (HXCPP_API_LEVEL>320)
if (inString==HX_CSTRING("__rtti"))
return __rtti__;
#endif
if (mGetStaticField)
{
Dynamic result;
if (mGetStaticField(inString,result,inCallProp))
return result;
// Throw ?
return null();
}
// Not the most efficient way of doing this!
if (!mConstructEmpty)
return null();
Dynamic instance = mConstructEmpty();
return instance->__Field(inString, inCallProp);
}
hx::Val Class_obj::__SetField(const String &inString,const hx::Val &inValue, hx::PropertyAccess inCallProp)
{
if (mSetStaticField)
{
Dynamic result = inValue;
if (mSetStaticField(inString,result,inCallProp))
return result;
// Throw ?
return inValue;
}
// Not the most efficient way of doing this!
if (!mConstructEmpty)
return null();
Dynamic instance = mConstructEmpty();
return instance->__SetField(inString,inValue, inCallProp);
}
bool Class_obj::__IsEnum()
{
return mConstructEnum || this==GetVoidClass().GetPtr() || this==GetBoolClass().GetPtr();
}
#ifdef HXCPP_SCRIPTABLE
const hx::StorageInfo* Class_obj::GetMemberStorage(String inName)
{
if (mMemberStorageInfo)
{
for(const StorageInfo *s = mMemberStorageInfo; s->offset; s++)
{
if (s->name == inName)
return s;
}
}
if (mSuper)
return (*mSuper)->GetMemberStorage(inName);
return 0;
}
const hx::StaticInfo* Class_obj::GetStaticStorage(String inName)
{
if (mStaticStorageInfo)
{
for(const StaticInfo *s = mStaticStorageInfo; s->address; s++)
{
if (s->name == inName)
return s;
}
}
return 0;
}
#endif
void MarkClassStatics(hx::MarkContext *__inCtx)
{
#ifdef HXCPP_DEBUG
MarkPushClass("MarkClassStatics",__inCtx);
#endif
ClassMap::iterator end = sClassMap->end();
for(ClassMap::iterator i = sClassMap->begin(); i!=end; ++i)
{
Class c = i->second;
if (c->__meta__.mPtr || c->mMarkFunc)
{
#ifdef HXCPP_DEBUG
hx::MarkPushClass(i->first.raw_ptr(),__inCtx);
hx::MarkSetMember("statics",__inCtx);
#endif
c->MarkStatics(__inCtx);
#ifdef HXCPP_DEBUG
hx::MarkPopClass(__inCtx);
#endif
}
}
#ifdef HXCPP_DEBUG
MarkPopClass(__inCtx);
#endif
}
#ifdef HXCPP_VISIT_ALLOCS
void VisitClassStatics(hx::VisitContext *__inCtx)
{
HX_VISIT_MEMBER(Class_obj__mClass);
ClassMap::iterator end = sClassMap->end();
for(ClassMap::iterator i = sClassMap->begin(); i!=end; ++i)
i->second->VisitStatics(__inCtx);
}
#endif
} // End namespace hx
Array<String> __hxcpp_get_class_list()
{
Array<String> result = Array_obj<String>::__new();
if (hx::sClassMap)
{
for(hx::ClassMap::iterator i=hx::sClassMap->begin(); i!=hx::sClassMap->end(); ++i)
{
if (i->second.mPtr)
result->push( i->first );
}
}
return result;
}