Handle<Value> TiRootObject::_require(void* userContext, TiObject* caller, const Arguments& args) { HandleScope scope; Local<Object> globalObject = TitaniumRuntime::getContenxt()->Global(); Handle<Value> nativeModule = TiModuleRegistry::GetModule(QString(*String::Utf8Value(args[0]->ToString()))); if(!nativeModule->IsUndefined()) { return scope.Close(nativeModule); } QString fileName = Ti::TiHelper::QStringFromValue(args[0]).append(".js"); QString filePath = Ti::TiHelper::getAssetPath(fileName).prepend("app/native/"); Local<Value> existingModule = globalObject->GetHiddenValue(Ti::TiHelper::ValueFromQString(fileName)->ToString()); if(!existingModule.IsEmpty() && !existingModule->IsUndefined()) { return scope.Close(existingModule); } QString js = readJsFile(filePath); if(js.isEmpty()) { ThrowException(String::New( QString("Module not found ").append(fileName).toLocal8Bit().constData() )); return scope.Close(Undefined()); } js.prepend("(function(){" "var __vars = {};" "__vars.exports = {};" "__vars.module = {exports:__vars.exports};" "var module = __vars.module;" "var exports = __vars.exports;"); js.append("\nreturn __vars.module.exports;" "})();"); Handle<Script> script = Script::Compile(Ti::TiHelper::ValueFromQString(js)->ToString() , Ti::TiHelper::ValueFromQString(fileName)); TryCatch tryCatch; if (script.IsEmpty()) { Ti::TiErrorScreen::ShowWithTryCatch(tryCatch); return scope.Close(Undefined()); } Persistent<Value> result = Persistent<Value>::New(script->Run()); result.MarkIndependent(); if (result.IsEmpty()) { Ti::TiErrorScreen::ShowWithTryCatch(tryCatch); return scope.Close(Undefined()); } globalObject->SetHiddenValue(Ti::TiHelper::ValueFromQString(fileName)->ToString(), result); return scope.Close(result); }
void MetadataNode::SetPackageMetadata(Isolate *isolate, Local<Object> value, MetadataNode *node) { value->SetHiddenValue(ConvertToV8String("tns::PackageMetadata"), External::New(isolate, node)); }
void MetadataNode::ExtendCallMethodHandler(const v8::FunctionCallbackInfo<v8::Value>& info) { if (info.IsConstructCall()) { string exMsg("Cannot call 'extend' as constructor"); ExceptionUtil::GetInstance()->ThrowExceptionToJs(exMsg); return; } SET_PROFILER_FRAME(); Local<Object> implementationObject; Local<String> extendName; string extendLocation; auto validArgs = ValidateExtendArguments(info, extendLocation, extendName, implementationObject); if (!validArgs) return; auto node = reinterpret_cast<MetadataNode*>(info.Data().As<External>()->Value()); DEBUG_WRITE("ExtendsCallMethodHandler: called with %s", ConvertToString(extendName).c_str()); string extendNameAndLocation = extendLocation + ConvertToString(extendName); auto fullClassName = TNS_PREFIX + CreateFullClassName(node->m_name, extendNameAndLocation); // //resolve class (pre-generated or generated runtime from dex generator) jclass resolvedClass = NativeScriptRuntime::ResolveClass(fullClassName, implementationObject); //resolve class returns GlobalRef std::string generatedFullClassName = s_objectManager->GetClassName(resolvedClass); // auto fullExtendedName = generatedFullClassName; DEBUG_WRITE("ExtendsCallMethodHandler: extend full name %s", fullClassName.c_str()); auto isolate = info.GetIsolate(); auto cachedData = GetCachedExtendedClassData(isolate, fullExtendedName); if (cachedData.extendedCtorFunction != nullptr) { auto cachedExtendedCtorFunc = Local<Function>::New(isolate, *cachedData.extendedCtorFunction); info.GetReturnValue().Set(cachedExtendedCtorFunc); return; } auto implementationObjectPropertyName = V8StringConstants::GetClassImplementationObject(); //reuse validation - checks that implementationObject is not reused for different classes auto implementationObjectProperty = implementationObject->GetHiddenValue(implementationObjectPropertyName).As<String>(); if (implementationObjectProperty.IsEmpty()) { //mark the implementationObject as such and set a pointer to it's class node inside it for reuse validation later implementationObject->SetHiddenValue(implementationObjectPropertyName, String::NewFromUtf8(isolate, fullExtendedName.c_str())); } else { string usedClassName = ConvertToString(implementationObjectProperty); stringstream s; s << "This object is used to extend another class '" << usedClassName << "'"; ExceptionUtil::GetInstance()->ThrowExceptionToJs(s.str()); return; } auto baseClassCtorFunc = node->GetConstructorFunction(isolate); auto extendData = External::New(isolate, new ExtendedClassData(node, extendNameAndLocation, implementationObject, fullExtendedName)); auto extendFuncTemplate = FunctionTemplate::New(isolate, ExtendedClassConstructorCallback, extendData); extendFuncTemplate->InstanceTemplate()->SetInternalFieldCount(static_cast<int>(ObjectManager::MetadataNodeKeys::END)); auto extendFunc = extendFuncTemplate->GetFunction(); auto prototypeName = ConvertToV8String("prototype"); implementationObject->SetPrototype(baseClassCtorFunc->Get(prototypeName)); implementationObject->SetAccessor(ConvertToV8String("super"), SuperAccessorGetterCallback, nullptr, implementationObject); auto extendFuncPrototype = extendFunc->Get(prototypeName).As<Object>(); auto p = extendFuncPrototype->GetPrototype(); extendFuncPrototype->SetPrototype(implementationObject); extendFunc->SetPrototype(baseClassCtorFunc); SetClassAccessor(extendFunc); SetTypeMetadata(isolate, extendFunc, new TypeMetadata(fullExtendedName)); info.GetReturnValue().Set(extendFunc); s_name2NodeCache.insert(make_pair(fullExtendedName, node)); ExtendedClassCacheData cacheData(extendFunc, fullExtendedName, node); s_extendedCtorFuncCache.insert(make_pair(fullExtendedName, cacheData)); }
void MetadataNode::SetInstanceMetadata(Isolate *isolate, Local<Object> value, MetadataNode *node) { auto key = Local<String>::New(isolate, *s_metadataKey); value->SetHiddenValue(key, External::New(isolate, node)); }
Handle<Object> WrapComponent(Handle<Object> wrappedes, ScriptSystem* scriptsys, dtEntity::EntityId eid, dtEntity::Component* v) { HandleScope handle_scope; Handle<Object> wrapped = scriptsys->GetFromComponentMap(v->GetType(), eid); if(!wrapped.IsEmpty()) { return wrapped; } Handle<FunctionTemplate> templt = GetScriptSystem()->GetTemplateBySID(s_componentWrapper); if(templt.IsEmpty()) { templt = FunctionTemplate::New(); templt->SetClassName(String::New("Component")); templt->InstanceTemplate()->SetInternalFieldCount(1); Handle<ObjectTemplate> proto = templt->PrototypeTemplate(); proto->Set("equals", FunctionTemplate::New(COEquals)); proto->Set("getType", FunctionTemplate::New(COGetType)); proto->Set("properties", FunctionTemplate::New(COProperties)); proto->Set("toString", FunctionTemplate::New(COToString)); proto->Set("finished", FunctionTemplate::New(COFinished)); proto->Set("copyPropertyValues", FunctionTemplate::New(COCopyPropertyValues)); GetScriptSystem()->SetTemplateBySID(s_componentWrapper, templt); } Local<Object> instance = templt->GetFunction()->NewInstance(); instance->SetInternalField(0, External::New(v)); instance->SetHiddenValue(scriptsys->GetEntityIdString(), Uint32::New(eid)); // GetStringFromSID and conversion to v8::String is costly, create a // hidden value in entity system wrapper that stores // strings and their string ids as name=>value pairs Handle<Value> propnamesval = wrappedes->GetHiddenValue(scriptsys->GetPropertyNamesString()); if(propnamesval.IsEmpty()) { Handle<Object> names = Object::New(); dtEntity::PropertyGroup::const_iterator i; const dtEntity::PropertyGroup& props = v->Get(); for(i = props.begin(); i != props.end(); ++i) { dtEntity::StringId sid = i->first; std::string propname = dtEntity::GetStringFromSID(sid); names->Set(String::New(propname.c_str()), WrapSID(sid)); } wrappedes->SetHiddenValue(scriptsys->GetPropertyNamesString(), names); propnamesval = names; } Handle<Object> propnames = Handle<Object>::Cast(propnamesval); Handle<Array> keys = propnames->GetPropertyNames(); for(unsigned int i = 0; i < keys->Length(); ++i) { Handle<String> str = keys->Get(i)->ToString(); dtEntity::StringId sid = UnwrapSID(propnames->Get(str)); dtEntity::Property* prop = v->Get(sid); if(prop == NULL) { LOG_ERROR("Could not find property in component: " << ToStdString(str)); continue; } Handle<External> ext = v8::External::New(static_cast<void*>(prop)); instance->SetAccessor(str, COPropertyGetter, COPropertySetter, ext); } // store wrapped component to script system scriptsys->AddToComponentMap(v->GetType(), eid, instance); return handle_scope.Close(instance); }