const char *platform_getWritablePath() { static utString path; if (path.size()) { return path.c_str(); } const char *tmp = LoomJni::getPackageName(); if (!tmp) { return ""; } // the path is: /data/data/ + package name path = "/data/data/"; if (tmp) { path += tmp; } else { return ""; } return path.c_str(); }
const char *LoomJni::getPackageName() { static utString packageName; if (packageName.size()) { return packageName.c_str(); } loomJniMethodInfo t; if (getStaticMethodInfo(t, "co/theengine/loomdemo/LoomDemo", "getActivityPackageName", "()Ljava/lang/String;")) { jstring str = (jstring)t.getEnv()->CallStaticObjectMethod(t.classID, t.methodID); t.getEnv()->DeleteLocalRef(t.classID); packageName = jstring2string(str); t.getEnv()->DeleteLocalRef(str); lmLog(jniLogGroup, "package name %s", packageName.c_str()); return packageName.c_str(); } return 0; }
void utStringUtils::replace( utString &in, const utString &from, const utString &to ) { if ( !from.empty() && from != to ) { // erase if ( to.empty() ) { size_t pos= 0; while ( pos != utString::npos ) { pos= in.find( from ); if ( pos != utString::npos ) in.erase( pos, from.size() ); } } else { size_t pos= 0; while ( pos != utString::npos ) { pos= in.find( from ); if ( pos != utString::npos ) { in.erase( pos, from.size() ); in.insert( pos, to ); } } } } }
const char *platform_getSettingsPath() { static utString path; if (path.size()) { return path.c_str(); } path = LoomJni::getSettingsPath(); return path.c_str(); }
void send() { if (url == "") { _OnFailureDelegate.pushArgument("Error: Empty URL"); _OnFailureDelegate.invoke(); } else { if (bodyBytes != NULL) { // Send with body as byte array. platform_HTTPSend((const char *)url.c_str(), (const char *)method.c_str(), &HTTPRequest::respond, (void *)this, (const char *)bodyBytes->getInternalArray()->ptr(), bodyBytes->getSize(), header, (const char *)responseCacheFile.c_str(), base64EncodeResponseData, followRedirects); } else { // Send with body as string. platform_HTTPSend((const char *)url.c_str(), (const char *)method.c_str(), &HTTPRequest::respond, (void *)this, (const char *)body.c_str(), body.length(), header, (const char *)responseCacheFile.c_str(), base64EncodeResponseData, followRedirects); } } }
void utStringUtils::split(utStringArray &rval, const utString &spl, const utString &expr ) { utString string= spl; rval.reserve( 32 ); for ( ;; ) { size_t pos= string.find_first_of( expr ); if ( pos != utString::npos ) { // chop first if ( pos == 0 ) pos= pos + 1; utString sub= string.substr( 0, pos ); if ( !sub.empty() && expr.find( sub ) == utString::npos ) rval.push_back( sub ); string.erase( 0, pos ); } else { if ( !string.empty() ) rval.push_back( string ); break; } } }
void LSCompiler::generateRootDependenciesRecursive(const utString& ref) { // We're either going to be compiling against an existing loom assembly // or compiling from a build file char cref[2048]; snprintf(cref, 2048, "%s", ref.c_str()); if (strstr(cref, ".loomlib")) { *(strstr(cref, ".loomlib")) = 0; } for (UTsize i = 0; i < rootBuildDependencies.size(); i++) { BuildInfo *buildInfo = rootBuildDependencies.at(i); if (buildInfo->getAssemblyName() == cref) { return; } } // first look in the src folders for an existing build file BuildInfo *buildInfo = loadBuildFile(cref); if (buildInfo) { utString assemblyLib = buildInfo->getOutputDir() + platform_getFolderDelimiter() + buildInfo->getAssemblyName() + ".loomlib"; // If the assembly is not built yet, build it if (!platform_mapFileExists(assemblyLib.c_str())) { for (UTsize i = 0; i < buildInfo->getNumReferences(); i++) { utString rref = buildInfo->getReference(i); generateRootDependenciesRecursive(rref); } rootBuildDependencies.push_back(buildInfo); } else { rootLibDependencies.push_back(ref); } } if (rootDependencies.find(ref) == UT_NPOS) { if (!buildInfo) { // we're compiling against a .loomlib and won't be rebuilding it rootLibDependencies.push_back(ref); } rootDependencies.push_back(ref); } }
// Helper to recognize an asset's type from its path/name. static int loom_asset_recognizeAssetTypeFromPath(utString& path) { // Easy out - empty strings are no good! if (path.length() == 0) { return 0; } // Walk backwards to first dot. size_t firstDotPos = path.size() - 1; for (size_t pos = path.size() - 1; pos > 0; pos--) { if (path.at(pos) != '.') { continue; } firstDotPos = pos; break; } // Split out the extension. utString pathExt = path.substr(firstDotPos + 1); // See if we can get a type out of any of the recognizers. int type = 0; for (UTsize i = 0; i < gRecognizerList.size(); i++) { type = gRecognizerList[i](pathExt.c_str()); if (type) { break; } } // No match, so let's use text. if (type == 0) { lmLogInfo(gAssetLogGroup, "Couldn't recognize '%s', defaulting to LATText...", path.c_str()); type = LATText; } return type; }
void LSLuaState::invokeStaticMethod(const utString& typePath, const char *methodName, int numParameters) { Type *type = getType(typePath.c_str()); lmAssert(type, "LSLuaState::invokeStaticMethod unknown type: %s", typePath.c_str()); MemberInfo *member = type->findMember(methodName); lmAssert(member, "LSLuaState::invokeStaticMethod unknown member: %s:%s", typePath.c_str(), methodName); if (!member->isMethod()) { lmAssert(0, "LSLuaState::invokeStaticMethod member: %s:%s is not a method", typePath.c_str(), methodName); } MethodInfo *method = (MethodInfo *)member; lmAssert(method->isStatic(), "LSLuaState::invokeStaticMethod member: %s:%s is not a static method", typePath.c_str(), methodName); method->invoke(NULL, numParameters); }
void AssemblyWriter::writeToFile(const utString& filename) { utString out; writeToString(out); // ... and write it utFileStream fs; fs.open(filename.c_str(), utStream::SM_WRITE); if (fs.isOpen()) { fs.write(out.c_str(), (int)out.size()); fs.close(); } else { LSError("Could not write to %s", filename.c_str()); } }
const char *LoomJni::getSettingsPath() { static utString path; loomJniMethodInfo t; if (getStaticMethodInfo(t, "co/theengine/loomplayer/LoomPlayer", "getActivitySettingsPath", "()Ljava/lang/String;")) { jstring str = (jstring)t.getEnv()->CallStaticObjectMethod(t.classID, t.methodID); path = jstring2string(str); t.getEnv()->DeleteLocalRef(str); lmLog(jniLogGroup, "settings path %s", path.c_str()); return path.c_str(); } return 0; }
const char *LoomJni::getWritablePath() { static utString writablePath; loomJniMethodInfo t; if (getStaticMethodInfo(t, "co/theengine/loomdemo/LoomDemo", "getActivityWritablePath", "()Ljava/lang/String;")) { jstring str = (jstring)t.getEnv()->CallStaticObjectMethod(t.classID, t.methodID); writablePath = jstring2string(str); t.getEnv()->DeleteLocalRef(str); lmLog(jniLogGroup, "writable path %s", writablePath.c_str()); return writablePath.c_str(); } return 0; }
void TypeCompiler::initCodeState(CodeState *codeState, FuncState *funcState, const utString& source) { memset(codeState, 0, sizeof(CodeState)); memset(funcState, 0, sizeof(FuncState)); codeState->L = vm->VM(); codeState->source = luaS_new(vm->VM(), source.c_str()); BC::openFunction(codeState, funcState); /* main func. is always vararg */ funcState->f->is_vararg = VARARG_ISVARARG; }
utString GetSDKPathFromLSCPath(utString const& lscPath) { char lsc[2048]; snprintf(lsc, 2048, "%s", lscPath.c_str()); // Slurp off the filename... unsigned int len = strlen(lsc) - 1; while (len-- > 0) { if ((lsc[len] == '\\') || (lsc[len] == '/')) { lsc[len + 1] = '\0'; break; } } // And go up the directories until we find one with "lib" in it... // But shouldn't be more than 3 bool found = false; for (int i = 0; i <= 3; i++) { utString searchLib(lsc); searchLib += "libs"; if (platform_dirExists(searchLib.c_str()) == 0) { found = true; break; } while (len-- > 0) { if ((lsc[len] == '\\') || (lsc[len] == '/')) { lsc[len + 1] = '\0'; // This won't cause a buffer overrun because // we already ate backwards in the previous loop. // But we do need to preserve the trailing slash. break; } } } if (!found) { printf("Unable to find SDK libraries somewhere inside %s\n", lsc); exit(EXIT_FAILURE); } return utString(lsc); }
// Instate new bits/type to the asset. void instate(int _type, void *bits, LoomAssetCleanupCallback dtor) { // Swap in a new blob. if(blob) blob->decRef(); blob = lmNew(gAssetAllocator) loom_assetBlob_t(); blob->incRef(); blob->bits = bits; blob->dtor = dtor; // Update the type. type = _type; // We're by definition loaded at this point. state = loom_asset_t::Loaded; // Fire subscribers. loom_asset_notifySubscribers(name.c_str()); }
void akBLoader::loadFile(const utString &filename, bool sortByMat, bool openglVertexColor) { fbtBlend fp; if (fp.parse(filename.c_str(), fbtFile::PM_COMPRESSED) != fbtFile::FS_OK) { return; } // current scne Blender::Scene* bscene = fp.m_fg->curscene; //animations akAnimationLoader animLoader(m_demo); animLoader.convertActions(fp.m_action, fp.getVersion() <= 249, bscene->r.frs_sec); //convert camera convertCameraObject(bscene->camera); //objects of the active scene for (Blender::Base* base = (Blender::Base*)bscene->base.first; base; base = base->next) { if (!base->object) continue; Blender::Object* bobj = base->object; // test for usable object type if(bobj->type == OB_MESH) { convertObjectMesh(bobj); akEntity* entity = m_demo->getEntity(AKB_IDNAME(bobj)); animLoader.convertObject(entity, bobj, fp.getVersion() <= 249, bscene->r.frs_sec); } } }
// this will always be in assets/loom.config (unless we decide to move it) void LoomApplicationConfig::parseApplicationConfig(const utString& jsonString) { configJSON = jsonString; // verify config is valid JSON json_error_t jerror; json_t *json = json_loadb(jsonString.c_str(), jsonString.length(), 0, &jerror); lmAssert(json, "LoomApplicationConfig::parseApplicationConfig() error parsing application config %s\n %s %i\n", jerror.source, jerror.text, jerror.line); if (json_t *wfaa = json_object_get(json, "waitForAssetAgent")) { _waitForAssetAgent = _jsonParseInt("waitForAssetAgent", wfaa); } if (json_t *ah = json_object_get(json, "assetAgentHost")) { if (!json_is_string(ah)) { lmLog(gLoomApplicationConfigLogGroup, "assetAgentHost was specified but is not a string!"); } else { assetHost = json_string_value(ah); } } if (json_t *ap = json_object_get(json, "assetAgentPort")) { assetPort = _jsonParseInt("assetAgentPort", ap); } const char *v = json_string_value(json_object_get(json, "version")); if (v != NULL) { _version = v; } const char *app_id = json_string_value(json_object_get(json, "app_id")); if (app_id != NULL) { _applicationId = app_id; } // Parse log block. if (json_t *logBlock = json_object_get(json, "log")) { // Walk the children. const char *key; json_t *value; json_object_foreach(logBlock, key, value) { // Key is the prefix for the rule. // Maybe we have level or enabled data? int enabledRule = -1; int filterRule = -1; if (json_t *enabledBlock = json_object_get(value, "enabled")) { enabledRule = _jsonParseBool("log.enabled", value); } // TODO: Allow info, warn, error as parameters here. if (json_t *levelBlock = json_object_get(value, "level")) { filterRule = (int)json_integer_value(levelBlock); } loom_log_addRule(key, enabledRule, filterRule); } }
virtual bool handleMessage(int fourcc, AssetProtocolHandler *handler, NetworkBuffer& buffer) { switch (fourcc) { case LOOM_FOURCC('F', 'I', 'L', 'E'): { // How many pending files? gPendingFiles = buffer.readInt(); loom_asset_notifyPendingCountChange(); // Read the filename. char *path; int fileStringLength; buffer.readString(&path, &fileStringLength); // And the file length. int bitsLength = buffer.readInt(); // Checkpoint at end! buffer.readCheckpoint(0xDEADBEE3); // Prepare the buffer! if (pendingFile != NULL) { lmLogError(gAssetLogGroup, "Got a new FILE '%s' while still processing existing file '%s'!", path, pendingFilePath.c_str()); wipePendingData(); } // Update the pending file state. pendingFilePath = path; lmFree(NULL, path); path = NULL; pendingFileLength = bitsLength; pendingFile = (const char *)lmAlloc(gAssetAllocator, pendingFileLength); // Log it. lmLogDebug(gAssetLogGroup, "FILE '%s' %d bytes incoming.", pendingFilePath.c_str(), bitsLength); // Awesome, sit back and wait for chunks to come in. return true; } case LOOM_FOURCC('F', 'C', 'H', 'K'): { // How many pending files? gPendingFiles = buffer.readInt(); loom_asset_notifyPendingCountChange(); // Get the offset. int chunkOffset = buffer.readInt(); // Read bits into the buffer. char *fileBits; int fileBitsLength; buffer.readString(&fileBits, &fileBitsLength); memcpy((void *)(pendingFile + chunkOffset), (void *)fileBits, fileBitsLength); lmFree(NULL, fileBits); // Checkpoint at end! buffer.readCheckpoint(0xDEADBEE2); int lastByteOffset = chunkOffset + fileBitsLength; // Log it. lmLogDebug(gAssetLogGroup, "FILE '%s' %d of %d bytes!", pendingFilePath.c_str(), lastByteOffset, pendingFileLength); // If it's the last one, instate it and wipe our buffer. if (lastByteOffset == pendingFileLength) { // And this resolves a file so decrement the pending count. This way // we will get to zero. gPendingFiles--; loom_asset_notifyPendingCountChange(); // Instate the new asset data. loom_asset_t *asset = loom_asset_getAssetByName(pendingFilePath.c_str(), 1); int assetType = loom_asset_recognizeAssetTypeFromPath(pendingFilePath); if (assetType == 0) { lmLogDebug(gAssetLogGroup, "Couldn't infer file type for '%s', ignoring.", pendingFilePath.c_str()); wipePendingData(); return true; } lmLogWarn(gAssetLogGroup, "Applying new version of '%s', %d bytes.", pendingFilePath.c_str(), pendingFileLength); LoomAssetCleanupCallback dtor = NULL; void *assetBits = loom_asset_deserializeAsset(pendingFilePath.c_str(), assetType, pendingFileLength, (void *)pendingFile, &dtor); asset->instate(assetType, assetBits, dtor); // And wipe the pending date. wipePendingData(); } } return true; } return false; }
const char *getError() { return _errorMsg.c_str(); }
void LSCompiler::linkRootAssembly(const utString& sjson) { json_error_t jerror; json_t *json = json_loadb((const char *)sjson.c_str(), sjson.length(), 0, &jerror); lmAssert(json, "Error linking assembly"); json_t *ref_array = json_object_get(json, "references"); lmAssert(json, "Error linking assembly, can't get executable references"); for (UTsize i = 0; i < rootBuildDependencies.size(); i++) { BuildInfo *buildInfo = rootBuildDependencies.at(i); utString assemblySource = buildInfo->getOutputDir() + platform_getFolderDelimiter() + buildInfo->getAssemblyName() + ".loomlib"; utArray<unsigned char> rarray; lmAssert(utFileStream::tryReadToArray(assemblySource, rarray), "Unable to load library assembly %s", assemblySource.c_str()); utBase64 base64 = utBase64::encode64(rarray); for (size_t j = 0; j < json_array_size(ref_array); j++) { json_t *jref = json_array_get(ref_array, j); utString jname = json_string_value(json_object_get(jref, "name")); if (buildInfo->getAssemblyName() == jname) { logVerbose("Linking: %s", jname.c_str()); json_object_set(jref, "binary", json_string(base64.getBase64().c_str())); json_object_set(jref, "uid", json_string(readAssemblyUID(rarray))); break; } } } // filter the reference array by the import assemblies utStack<int> filter; for (size_t j = 0; j < json_array_size(ref_array); j++) { json_t *jref = json_array_get(ref_array, j); utString jname = json_string_value(json_object_get(jref, "name")); bool found = false; // always find the System assembly, so we don't have to explicitly import from it if (jname == "System") { found = true; } for (UTsize k = 0; k < importedAssemblies.size() && !found; k++) { if (importedAssemblies.at(k)->getName() == jname) { found = true; break; } } if (!found) { filter.push((int)j); } } while (filter.size()) { json_array_remove(ref_array, filter.pop()); } for (UTsize i = 0; i < rootLibDependencies.size(); i++) { utString libName = rootLibDependencies.at(i); for (size_t j = 0; j < json_array_size(ref_array); j++) { json_t *jref = json_array_get(ref_array, j); utString jname = json_string_value(json_object_get(jref, "name")); if (libName != jname) { continue; } log("Linking: %s", libName.c_str()); utString delim = platform_getFolderDelimiter(); utString libPath = sdkPath + delim + "libs" + delim + libName + ".loomlib"; utArray<unsigned char> rarray; if (libName == "System" && embeddedSystemAssembly) { size_t embeddedSystemAssemblyLength = strlen(embeddedSystemAssembly); rarray.resize((int)(embeddedSystemAssemblyLength + 1)); memcpy(&rarray[0], embeddedSystemAssembly, embeddedSystemAssemblyLength + 1); } else { lmAssert(utFileStream::tryReadToArray(libPath, rarray), "Unable to load library assembly %s at %s", libName.c_str(), libPath.c_str()); } utBase64 base64 = utBase64::encode64(rarray); json_object_set(jref, "binary", json_string(base64.getBase64().c_str())); json_object_set(jref, "uid", json_string(readAssemblyUID(rarray))); break; } } json_object_set(json, "executable", json_true()); utString execSource = rootBuildInfo->getOutputDir() + utString(platform_getFolderDelimiter()) + rootBuildInfo->getAssemblyName() + ".loom"; // generate binary assembly for executable BinWriter::writeExecutable(execSource.c_str(), json); log("Compile Successful: %s\n", execSource.c_str()); }
// We don't track every file. This function filters potential files. static bool checkInWhitelist(utString path) { // Note the platform-specific version of our whitelisted folders. static utString assetPath = "./assets"; platform_normalizePath(const_cast<char*>(assetPath.c_str())); static utString binPath = "./bin"; platform_normalizePath(const_cast<char*>(binPath.c_str())); static utString srcPath = "./src"; platform_normalizePath(const_cast<char*>(srcPath.c_str())); // Just prefix match against assets for now - ignore things in other folders. lmLogDebug(gAssetAgentLogGroup, "Whitelisting path %s prefix %s\n", path.c_str(), path.substr(0, 6).c_str()); platform_normalizePath(const_cast<char*>(path.c_str())); if (path.substr(path.length() - 3, 3) == "tmp") { return false; } if (path.substr(0, 8) == assetPath) { return true; } if (path.substr(0, 5) == srcPath) { return true; } if (path.substr(0, 5) == binPath) { return true; } return false; }
void utStringUtils::upper( utString &str ) { std::transform( str.begin(), str.end(), str.begin(), toupper ); }
void utStringUtils::trim( utString &in, const utString &expr ) { in.erase( in.find_last_not_of( expr ) + 1 ); in.erase( 0, in.find_first_not_of( expr ) ); }