//---------------------------------------------------------------------- // 構造体比較関数 bool ScriptsAdd::equalStruct(tTJSVariant v1, tTJSVariant v2) { // タイプがオブジェクトなら特殊判定 if (v1.Type() == tvtObject && v2.Type() == tvtObject) { if (v1.AsObjectNoAddRef() == v2.AsObjectNoAddRef()) return true; tTJSVariantClosure &o1 = v1.AsObjectClosureNoAddRef(); tTJSVariantClosure &o2 = v2.AsObjectClosureNoAddRef(); // 関数どうしなら特別扱いで関数比較 if (o1.IsInstanceOf(0, NULL, NULL, L"Function", NULL)== TJS_S_TRUE && o2.IsInstanceOf(0, NULL, NULL, L"Function", NULL)== TJS_S_TRUE) return v1.DiscernCompare(v2); // Arrayどうしなら全項目を比較 if (o1.IsInstanceOf(0, NULL, NULL, L"Array", NULL)== TJS_S_TRUE && o2.IsInstanceOf(0, NULL, NULL, L"Array", NULL)== TJS_S_TRUE) { // 長さが一致していなければ比較失敗 tTJSVariant o1Count, o2Count; (void)o1.PropGet(0, L"count", &countHint, &o1Count, NULL); (void)o2.PropGet(0, L"count", &countHint, &o2Count, NULL); if (! o1Count.DiscernCompare(o2Count)) return false; // 全項目を順番に比較 tjs_int count = o1Count; tTJSVariant o1Val, o2Val; for (tjs_int i = 0; i < count; i++) { (void)o1.PropGetByNum(TJS_IGNOREPROP, i, &o1Val, NULL); (void)o2.PropGetByNum(TJS_IGNOREPROP, i, &o2Val, NULL); if (! equalStruct(o1Val, o2Val)) return false; } return true; } // Dictionaryどうしなら全項目を比較 if (o1.IsInstanceOf(0, NULL, NULL, L"Dictionary", NULL)== TJS_S_TRUE && o2.IsInstanceOf(0, NULL, NULL, L"Dictionary", NULL)== TJS_S_TRUE) { // 項目数が一致していなければ比較失敗 tjs_int o1Count, o2Count; (void)o1.GetCount(&o1Count, NULL, NULL, NULL); (void)o2.GetCount(&o2Count, NULL, NULL, NULL); if (o1Count != o2Count) return false; // 全項目を順番に比較 DictMemberCompareCaller *caller = new DictMemberCompareCaller(o2); tTJSVariantClosure closure(caller); tTJSVariant(o1.EnumMembers(TJS_IGNOREPROP, &closure, NULL)); bool result = caller->match; caller->Release(); return result; } } return v1.DiscernCompare(v2); }
// 実行 bool exec(iTJSDispatch2 *obj, tTVPWindowMessage *message) { switch (receiver.Type()) { case tvtObject: { tTJSVariant result; tTJSVariant wparam = (tjs_int)message->WParam; tTJSVariant lparam = (tjs_int)message->LParam; tTJSVariant *p[] = {&userData, &wparam, &lparam}; receiver.AsObjectClosureNoAddRef().FuncCall(0, NULL, NULL, &result, 3, p, NULL); return (int)result != 0; } break; case tvtString: { tTJSVariant result; tTJSVariant wparam = (tjs_int)message->WParam; tTJSVariant lparam = (tjs_int)message->LParam; tTJSVariant *p[] = {&userData, &wparam, &lparam}; obj->FuncCall(0, receiver.GetString(), NULL, &result, 3, p, obj); return (int)result != 0; } break; case tvtInteger: { NativeReceiver receiverNative = (NativeReceiver)(tjs_int)receiver; return receiverNative(obj, (void*)(tjs_int)userData, message); } break; } return false; }
//---------------------------------------------------------------------- // 構造体比較関数 tTJSVariant ScriptsAdd::clone(tTJSVariant obj) { // タイプがオブジェクトなら細かく判定 if (obj.Type() == tvtObject) { tTJSVariantClosure &o1 = obj.AsObjectClosureNoAddRef(); // Arrayの複製 if (o1.IsInstanceOf(0, NULL, NULL, L"Array", NULL)== TJS_S_TRUE) { iTJSDispatch2 *array = TJSCreateArrayObject(); tTJSVariant o1Count; (void)o1.PropGet(0, L"count", &countHint, &o1Count, NULL); tjs_int count = o1Count; tTJSVariant val; tTJSVariant *args[] = {&val}; for (tjs_int i = 0; i < count; i++) { (void)o1.PropGetByNum(TJS_IGNOREPROP, i, &val, NULL); val = ScriptsAdd::clone(val); static tjs_uint addHint = 0; (void)array->FuncCall(0, TJS_W("add"), &addHint, 0, 1, args, array); } tTJSVariant result(array, array); array->Release(); return result; } // Dictionaryの複製 if (o1.IsInstanceOf(0, NULL, NULL, L"Dictionary", NULL)== TJS_S_TRUE) { iTJSDispatch2 *dict = TJSCreateDictionaryObject(); DictMemberCloneCaller *caller = new DictMemberCloneCaller(dict); tTJSVariantClosure closure(caller); o1.EnumMembers(TJS_IGNOREPROP, &closure, NULL); caller->Release(); tTJSVariant result(dict, dict); dict->Release(); return result; } // cloneメソッドの呼び出しに成功すればそれを返す tTJSVariant result; static tjs_uint cloneHint = 0; if (o1.FuncCall(0, L"clone", &cloneHint, &result, 0, NULL, NULL)== TJS_S_TRUE) { return result; } } return obj; }
/** * コンテキストが null かどうか判定 */ bool ScriptsAdd::isNullContext(tTJSVariant obj) { return obj.AsObjectClosureNoAddRef().ObjThis == NULL; }
/** * コンテキストの取得 */ tTJSVariant ScriptsAdd::getObjectContext(tTJSVariant obj) { iTJSDispatch2 *objthis = obj.AsObjectClosureNoAddRef().ObjThis; return tTJSVariant(objthis, objthis); }