bool CSComponentAssembly::PreloadClassAssemblies() { // TEMPORARY SOLUTION, Desktop only ATOMIC_LOGINFO("Preloading Class Assemblies"); Context* context = ScriptSystem::GetContext(); assert(context); ResourceCache* cache = context->GetSubsystem<ResourceCache>(); FileSystem* fileSystem = context->GetSubsystem<FileSystem>(); const StringVector& resourceDirs = cache->GetResourceDirs(); for (unsigned i = 0; i < resourceDirs.Size(); i++) { const String& resourceDir = resourceDirs[i]; ATOMIC_LOGINFOF("Scanning: %s", resourceDir.CString()); StringVector results; fileSystem->ScanDir(results, resourceDir, "*.dll", SCAN_FILES, true); for (unsigned j = 0; j < results.Size(); j++) { // FIXME: This filtering is necessary as we're loading setting project root folder as a resource dir // https://github.com/AtomicGameEngine/AtomicGameEngine/issues/1037 String filter = results[j].ToLower(); if (filter.StartsWith("atomicnet/") || filter.StartsWith("resources/")) { ATOMIC_LOGINFOF("Skipping Assembly: %s (https://github.com/AtomicGameEngine/AtomicGameEngine/issues/1037)", results[j].CString()); continue; } ATOMIC_LOGINFOF("Loading Assembly: %s", results[j].CString()); cache->GetResource<CSComponentAssembly>(results[j]); } } return true; }
// see http://duktape.org/guide.html#modules static int js_module_search(duk_context* ctx) { JSVM* vm = JSVM::GetJSVM(ctx); FileSystem* fs = vm->GetSubsystem<FileSystem>(); ResourceCache* cache = vm->GetSubsystem<ResourceCache>(); int top = duk_get_top(ctx); assert(top == 4); String moduleID = duk_to_string(ctx, 0); if (top > 1) { // require function assert(duk_is_function(ctx, 1)); } if (top > 2) { // exports assert(duk_is_object(ctx, 2)); } if (top > 3) { // module (module.id == a resolved absolute identifier for the module being loaded) assert(duk_is_object(ctx, 3)); } String pathName, fileName, extension; SplitPath(moduleID, pathName, fileName, extension); String path = moduleID; // Do we really want this? It is nice to not have to specify the Atomic path if (fileName.StartsWith("Atomic")) { path = "AtomicModules/" + path + ".js"; } else { path += ".js"; if (!cache->Exists(path)) { const Vector<String>& searchPaths = vm->GetModuleSearchPaths(); for (unsigned i = 0; i < searchPaths.Size(); i++) { String search = searchPaths[i] + path; if (cache->Exists(search)) { path = search; break; } } } } if (cache->Exists(path)) { SharedPtr<File> jsfile(cache->GetFile(path, false)); vm->SetLastModuleSearchFile(jsfile->GetFullPath()); String source; jsfile->ReadText(source); source.Append('\n'); duk_push_string(ctx, source.CString()); return 1; } else { // we're not a JS file, so check if we're a native module const Vector<String>& resourceDirs = cache->GetResourceDirs(); for (unsigned i = 0; i < resourceDirs.Size(); i++) { String pluginLibrary; // TODO: proper platform folder detection #ifdef ATOMIC_PLATFORM_WINDOWS pluginLibrary = resourceDirs.At(i) + "Plugins/Windows/x64/" + moduleID + ".dll"; #elif ATOMIC_PLATFORM_OSX pluginLibrary = resourceDirs.At(i) + "Plugins/Mac/x64/lib" + moduleID + ".dylib"; #endif if (pluginLibrary.Length() && fs->FileExists(pluginLibrary)) { // let duktape know we loaded a native module if (jsplugin_load(vm, pluginLibrary)) { duk_push_undefined(ctx); return 1; } else { duk_push_sprintf(ctx, "Failed loading native plugins: %s", pluginLibrary.CString()); duk_throw(ctx); } } } } duk_push_sprintf(ctx, "Failed loading module: %s", path.CString()); duk_throw(ctx); }