// This is the entry point for the file watcher thread. It scans local files // for changes and processes the diffs with processFileEntryDeltas. static int fileWatcherThread(void *payload) { // Start with a sane state so we don't stream everything. utArray<FileEntry> *oldState = generateFileState("."); // Loop forever looking for changes. for ( ; ; ) { int startTime = platform_getMilliseconds(); utArray<FileEntry> *newState = generateFileState("."); utArray<FileEntryDelta> *deltas = compareFileEntries(oldState, newState); int endTime = platform_getMilliseconds(); if (endTime - startTime > 250) { lmLogWarn(gAssetAgentLogGroup, "Scanning files took %dms, consider removing unused files", endTime - startTime); } processFileEntryDeltas(deltas); lmDelete(NULL, deltas); // Make the new state the old state and clean up the old state. lmDelete(NULL, oldState); oldState = newState; // Wait a bit so we don't saturate disk or CPU. loom_thread_sleep(gFileCheckInterval); } }
static jclass getClassID_(const char *className, JNIEnv *env) { JNIEnv *pEnv = env; jclass ret = 0; do { if (!pEnv) { if (!getEnv(&pEnv)) { break; } } ret = pEnv->FindClass(className); if (!ret) { lmLogWarn(jniLogGroup, "Failed to find class of %s", className); jthrowable exc; exc = pEnv->ExceptionOccurred(); if (exc) { pEnv->ExceptionClear(); } break; } } while (0); return ret; }
static bool getMethodInfo_(loomJniMethodInfo& methodinfo, const char *className, const char *methodName, const char *paramCode) { jmethodID methodID = 0; JNIEnv *pEnv = 0; bool bRet = false; do { if (!getEnv(&pEnv)) { break; } jclass classID = getClassID_(className, pEnv); if (!classID) { return false; } methodID = pEnv->GetMethodID(classID, methodName, paramCode); if (!methodID) { lmLogWarn(jniLogGroup, "Failed to find method id of %s", methodName); break; } methodinfo.classID = classID; methodinfo.methodID = methodID; bRet = true; } while (0); return bRet; }
void NativeDelegate::assertMainThread() { if(smMainThreadID == scmBadThreadID) { lmLogWarn(gNativeDelegateGroup, "Tried to touch a NativeDelegate before the main thread was marked. " "Probably need to add a markMainThread call?"); } if( smMainThreadID != platform_getCurrentThreadId()) { lmLogWarn(gNativeDelegateGroup, "Trying to fire a NativeDelegate from thread %x that is not the main " "thread %x. This will result in memory corruption and race conditions!", platform_getCurrentThreadId(), smMainThreadID); } }
static void loadDefaultFontFace() { lmLogWarn(gGFXVectorRendererLogGroup, "Warning: TextFormat font face not specified, using predefined default system font"); void* mem; size_t size; bool success = readDefaultFontFaceBytes(&mem, &size); if (!success) { defaultFontId = VectorTextFormat::FONT_DEFAULTMISSING; return; } int handle = nvgCreateFontMem(nvg, "__default", (unsigned char*)mem, size, true); if (handle == -1) { customFree(mem); defaultFontId = VectorTextFormat::FONT_DEFAULTMEMORY; return; } defaultFontId = handle; }
float display_getDPI() { loomJniMethodInfo t; if (LoomJni::getStaticMethodInfo(t , "co/theengine/loomplayer/LoomPlayer" , "getDPI" , "()F")) { jfloat p = (jint)t.getEnv()->CallStaticFloatMethod(t.classID, t.methodID); t.getEnv()->DeleteLocalRef(t.classID); return p; } lmLogWarn(gPlatformDisplayAndroidErrorLogGroup, "Failed to get DPI."); return 200; }
void loom_asset_unlock( const char *name ) { // Hack to report usage. //size_t allocBytes, allocCount; //loom_allocator_getTrackerProxyStats(gAssetAllocator, &allocBytes, &allocCount); //lmLogError(gAssetLogGroup, "Seeing %d bytes of allocator and %d allocations", allocBytes, allocCount); loom_mutex_lock(gAssetLock); // TODO: This needs to be against the blob we locked NOT the asset's // current state. // Look it up. loom_asset_t *asset = loom_asset_getAssetByName(name, 0); // Assert if not loaded. lmAssert(asset, "Could not find asset '%s' to unlock!", name); //lmAssert(asset->blob, "Asset was not locked!"); if(asset->state == loom_asset_t::Loaded) { // Dec count. if(asset->blob->decRef()) { asset->state = loom_asset_t::Unloaded; asset->blob = NULL; } } else { // Nothing - it's not loaded. lmLogWarn(gAssetLogGroup, "Couldn't unlock '%s' as it was not loaded.", name); } loom_mutex_unlock(gAssetLock); }
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; }
// Entry point for the socket thread. Listen for connections and incoming data, // and route it to the protocol handlers. static int socketListeningThread(void *payload) { // Listen for incoming connections. int listenPort = 12340; gListenSocket = (loom_socketId_t)-1; for ( ; ; ) { gListenSocket = loom_net_listenTCPSocket(listenPort); if (gListenSocket != (loom_socketId_t)-1) { break; } lmLogWarn(gAssetAgentLogGroup, " - Failed to acquire port %d, trying port %d", listenPort, listenPort + 1); listenPort++; } lmLog(gAssetAgentLogGroup, "Listening on port %d", listenPort); while (loom_socketId_t acceptedSocket = loom_net_acceptTCPSocket(gListenSocket)) { // Check to see if we got anybody... if (!acceptedSocket || ((int)(long)acceptedSocket == -1)) { // Process the connections. loom_mutex_lock(gActiveSocketsMutex); for (UTsize i = 0; i < gActiveHandlers.size(); i++) { AssetProtocolHandler* aph = gActiveHandlers[i]; aph->process(); // Check for ping timeout int msSincePing = loom_readTimer(aph->lastActiveTime); if (msSincePing > socketPingTimeoutMs) { gActiveHandlers.erase(i); i--; lmLog(gAssetAgentLogGroup, "Client timed out (%x)", aph->socket); loom_net_closeTCPSocket(aph->socket); lmDelete(NULL, aph); } } loom_mutex_unlock(gActiveSocketsMutex); loom_thread_sleep(10); continue; } lmLog(gAssetAgentLogGroup, "Client connected (%x)", acceptedSocket); loom_mutex_lock(gActiveSocketsMutex); gActiveHandlers.push_back(lmNew(NULL) AssetProtocolHandler(acceptedSocket)); AssetProtocolHandler *handler = gActiveHandlers.back(); handler->registerListener(lmNew(NULL) TelemetryListener()); if (TelemetryServer::isRunning()) handler->sendCommand("telemetryEnable"); // Send it all of our files. // postAllFiles(gActiveHandlers[gActiveHandlers.size()-1]->getId()); loom_mutex_unlock(gActiveSocketsMutex); } return 0; }