/** * 吉里吉里クラスから Javascript クラスを生成 * @param args 引数 * @return 結果 */ void TJSInstance::createTJSClass(const FunctionCallbackInfo<Value>& args) { Isolate *isolate = args.GetIsolate(); HandleScope handle_scope(isolate); if (args.Length() < 1) { args.GetReturnValue().Set(isolate->ThrowException(String::NewFromUtf8(isolate, "invalid param"))); return; } // TJSクラス情報取得 String::Value tjsClassName(args[0]); tTJSVariant tjsClassObj; TVPExecuteExpression(*tjsClassName, &tjsClassObj); if (tjsClassObj.Type() != tvtObject || TJS_FAILED(tjsClassObj.AsObjectClosureNoAddRef().IsInstanceOf(0,NULL,NULL,L"Class",NULL))) { args.GetReturnValue().Set(isolate->ThrowException(String::NewFromUtf8(isolate, "invalid param"))); return; } // クラステンプレートを生成 Local<FunctionTemplate> classTemplate = FunctionTemplate::New(isolate, tjsConstructor, TJSObject::toJSObject(isolate, tjsClassObj)); classTemplate->SetClassName(args[0]->ToString()); // 表示名 // メンバ登録処理 for (int i=args.Length()-1;i>=0;i--) { String::Value className(args[i]); tTJSVariant classObj; TVPExecuteExpression(*className, &classObj); if (classObj.Type() == tvtObject && TJS_SUCCEEDED(classObj.AsObjectClosureNoAddRef().IsInstanceOf(0,NULL,NULL,L"Class",NULL))) { MemberRegister *caller = new MemberRegister(isolate, classTemplate); tTJSVariantClosure closure(caller); classObj.AsObjectClosureNoAddRef().EnumMembers(TJS_IGNOREPROP, &closure, NULL); caller->Release(); } } // TJS機能メソッドを登録 Local<ObjectTemplate> protoTemplate = classTemplate->PrototypeTemplate(); protoTemplate->Set(String::NewFromUtf8(isolate, "tjsIsValid"), FunctionTemplate::New(isolate, tjsIsValid)); protoTemplate->Set(String::NewFromUtf8(isolate, "tjsOverride"), FunctionTemplate::New(isolate, tjsOverride)); args.GetReturnValue().Set(classTemplate->GetFunction()); }
/** * クラスの登録 * @param HSQUIRRELVM v */ SQRESULT TJSObject::createTJSClass(HSQUIRRELVM v) { SQInteger top = sq_gettop(v); if (top < 2) { return sq_throwerror(v, _SC("invalid param")); } // クラスを生成 sq_pushobject(v, SQClassType<TJSObject>::ClassObject()); sq_newclass(v, true); // 継承する // メンバ登録 const tjs_char *tjsClassName = NULL; tTJSVariant tjsClassObj; for (SQInteger i=top; i>1; i--) { if ((tjsClassName = sqobject::getString(v,i))) { TVPExecuteExpression(tjsClassName, &tjsClassObj); if (tjsClassObj.Type() == tvtObject && TJS_SUCCEEDED(tjsClassObj.AsObjectClosureNoAddRef().IsInstanceOf(0,NULL,NULL,L"Class",NULL))) { MemberRegister *r = new MemberRegister(v, tjsClassObj); tTJSVariantClosure closure(r); tjsClassObj.AsObjectClosureNoAddRef().EnumMembers(TJS_IGNOREPROP, &closure, NULL); r->Release(); } } } if (tjsClassName) { // コンストラクタ登録 sq_pushstring(v, _SC("constructor"), -1); sq_pushvariant(v, tjsClassObj); sq_newclosure(v, tjsConstructor, 1); sq_createslot(v, -3); // クラス属性に tjsクラスを登録 sq_pushnull(v); sq_newtable(v); if (SQ_SUCCEEDED(sq_setattributes(v,-3))) { sq_pop(v,1); sq_pushnull(v); if (SQ_SUCCEEDED(sq_getattributes(v, -2))) { sq_pushstring(v, tjsClassAttrName, -1); sq_pushvariant(v, tjsClassObj); if (SQ_SUCCEEDED(sq_createslot(v, -3))) { sq_pop(v,1); } else { sq_pop(v,2); } } else { // XXX sq_pop(v,1); } } else { // XXX sq_pop(v,2); } // TJS機能メソッドを登録 sq_pushstring(v, _SC("tjsIsValid"), -1); sq_newclosure(v, TJSObject::tjsIsValid, 0); sq_createslot(v, -3); sq_pushstring(v, _SC("tjsOverride"), -1); sq_newclosure(v, TJSObject::tjsOverride, 0); sq_setparamscheck(v, -2, _SC(".sc")); sq_createslot(v, -3); } return 1; }