#include #undef RegisterClass namespace hx { Dynamic FieldMapCreate() { return Dynamic(); } bool FieldMapGet(FieldMap *inMap, const String &inName, Dynamic &outValue) { if (!inMap || !inMap->mPtr) return false; if (!__string_hash_exists(*inMap,inName)) return false; outValue = __string_hash_get(*inMap, inName); return true; } bool FieldMapGet(FieldMap *inMap, int inId, Dynamic &outValue) { if (!inMap || !inMap->mPtr) return false; const String &key = __hxcpp_field_from_id(inId); if (!__string_hash_exists(*inMap,key)) return false; outValue = __string_hash_get(*inMap, key); return true; } bool FieldMapHas(FieldMap *inMap, const String &inName) { return inMap && inMap->mPtr && __string_hash_exists(*inMap,inName); } #ifdef HXCPP_GC_GENERATIONAL void FieldMapSet(hx::Object *inThis,FieldMap *inMap, const String &inName, const Dynamic &inValue) { __string_hash_set(inThis,*inMap, inName, inValue,true); } #else void FieldMapSet(FieldMap *inMap, const String &inName, const Dynamic &inValue) { __string_hash_set(*inMap, inName, inValue,true); } #endif void FieldMapAppendFields(FieldMap *inMap,Array &outFields) { Array keys = __string_hash_keys(*inMap); if (outFields->length==0) outFields = keys; else outFields = outFields->concat(keys); } // -- Anon_obj ------------------------------------------------- Anon_obj::Anon_obj(int inElements) { mFixedFields = inElements; //mFields = hx::FieldMapCreate(); } void Anon_obj::__Mark(hx::MarkContext *__inCtx) { if (mFixedFields) { VariantKey *fixed = getFixed(); for(int i=0;isought) return -1; if (fixed[min].hash!=sought) { int max = mFixedFields; if (fixed[max-1].hashmin+1) { int mid = (max+min)>>1; if (fixed[mid].hash <= sought) min = mid; else max = mid; } } while(fixed[min].hash==sought) { // Might be multiple? if ( fixed[min].key.length == inKey.length && !memcmp(fixed[min].key.raw_ptr(),inKey.raw_ptr(), inKey.length)) return min; min++; if (min>=mFixedFields) break; } return -1; } hx::Val Anon_obj::__Field(const String &inName, hx::PropertyAccess inCallProp) { #ifdef HX_SMART_STRINGS if (inName.isAsciiEncodedQ()) #endif if (mFixedFields>0) { VariantKey *fixed = getFixed(); if (inName.__s[HX_GC_CONST_ALLOC_MARK_OFFSET] & HX_GC_CONST_ALLOC_MARK_BIT) { for(int i=0;ihash==hash && HX_QSTR_EQ_AE(fixed->key,inName)) return fixed->value; if (mFixedFields>1) { fixed++; if (fixed->hash==hash && HX_QSTR_EQ_AE(fixed->key,inName)) return fixed->value; if (mFixedFields>2) { fixed++; if (fixed->hash==hash && HX_QSTR_EQ_AE(fixed->key,inName)) return fixed->value; if (mFixedFields>3) { fixed++; if (fixed->hash==hash && HX_QSTR_EQ_AE(fixed->key,inName)) return fixed->value; if (mFixedFields>4) { fixed++; if (fixed->hash==hash && HX_QSTR_EQ_AE(fixed->key,inName)) return fixed->value; int fixed = findFixed(inName,true); if (fixed>=0) return getFixed()[fixed].value; } } } } } if (!mFields.mPtr) return hx::Val(); return __string_hash_get(mFields,inName); } bool Anon_obj::__HasField(const String &inName) { if (findFixed(inName)>=0) return true; if (!mFields.mPtr) return false; return __string_hash_exists(mFields,inName); } bool Anon_obj::__Remove(String inKey) { int slot = findFixed(inKey); if (slot>=0) { VariantKey *fixed = getFixed(); while(slot=0) { #ifdef HXCPP_GC_GENERATIONAL VariantKey *fixed = getFixed() + slot; fixed->value=inValue; if (fixed->value.type <= cpp::Variant::typeString) HX_OBJ_WB_GET(this, fixed->value.valObject); #else getFixed()[slot].value=inValue; #endif return inValue; } // TODO - fixed if (!mFields.mPtr) { mFields = hx::FieldMapCreate(); HX_OBJ_WB_GET(this, mFields.mPtr); } __string_hash_set(HX_MAP_THIS_ mFields,inName,inValue,true); return inValue; } Anon_obj *Anon_obj::Add(const String &inName,const Dynamic &inValue,bool inSetThisPointer) { // TODO - fixed if (!mFields.mPtr) { mFields = hx::FieldMapCreate(); HX_OBJ_WB_GET(this, mFields.mPtr); } __string_hash_set(HX_MAP_THIS_ mFields,inName,inValue,true); if (inSetThisPointer && inValue.GetPtr()) inValue.GetPtr()->__SetThis(this); return this; } static int _hx_toString_depth = 0; String Anon_obj::toString() { if (!mFields.mPtr && !mFixedFields) return HX_CSTRING("{ }"); if (_hx_toString_depth >= 5) return HX_CSTRING("..."); _hx_toString_depth++; try { int fixedToString = findFixed(HX_CSTRING("toString")); if (fixedToString>=0) { Dynamic func = getFixed()[fixedToString].value; if (func!=null()) { String res = func(); _hx_toString_depth--; return res; } } Dynamic func; if (FieldMapGet(&mFields, HX_CSTRING("toString"), func)) { String res = func(); _hx_toString_depth--; return res; } if (mFixedFields) { Array array = Array(0,mFixedFields*4+4); array->push(HX_CSTRING("{ ")); if (mFields.mPtr) { String val = __string_hash_to_string_raw(mFields); if (val.raw_ptr()) array->push(val); } VariantKey *fixed = getFixed(); for(int i=0;ilength>1) array->push(HX_CSTRING(", ")); array->push(fixed[i].key); array->push(HX_CSTRING(" => ")); array->push(fixed[i].value); } array->push(HX_CSTRING(" }")); _hx_toString_depth--; return array->join(HX_CSTRING("")); } String ret = __string_hash_to_string(mFields); _hx_toString_depth--; return ret; } catch (...) { _hx_toString_depth--; throw; } } void Anon_obj::__GetFields(Array &outFields) { if (mFields.mPtr) outFields = __string_hash_keys(mFields); if (mFixedFields>0) { VariantKey *fixed = getFixed(); for(int i=0;ipush( fixed[i].key ); } } String Anon_obj::__ToString() const { return HX_CSTRING("Anon"); } Dynamic Anon_obj::__Create(DynamicArray inArgs) { return Anon(new (0) Anon_obj); } hx::Class Anon_obj::__mClass; void Anon_obj::__boot() { Static(__mClass) = hx::_hx_RegisterClass(HX_CSTRING("__Anon"),TCanCast,sNone,sNone,0,0,0,0); } Anon SourceInfo(String inFile, int inLine, String inClass, String inMethod) { Anon result = Anon_obj::Create(); result->Add(HX_CSTRING("fileName"),inFile); result->Add(HX_CSTRING("lineNumber"),inLine); result->Add(HX_CSTRING("className"),inClass); result->Add(HX_CSTRING("methodName"),inMethod); return result; } String StringFromAnonFields(hx::Object *inPtr) { Array fields = Array_obj::__new(); inPtr->__GetFields(fields); int n = fields->length; Array array = Array(0,n*4+4); array->push(HX_CSTRING("{ ")); for(int i=0;ilength>1) array->push(HX_CSTRING(", ")); array->push(fields[i]); array->push(HX_CSTRING(" => ")); array->push( inPtr->__Field( fields[i], HX_PROP_DYNAMIC) ); } array->push(HX_CSTRING(" }")); return array->join(HX_CSTRING("")); } } bool __hxcpp_anon_remove(Dynamic inObj,String inKey) { hx::Anon_obj *anon = dynamic_cast(inObj.mPtr); if (anon) { bool removed = anon->__Remove(inKey); if (removed) return true; } Dynamic *map = inObj->__GetFieldMap(); if (map) return __string_hash_remove(*map,inKey); return false; }