コード例 #1
0
ファイル: main.cpp プロジェクト: Y-way/LoomSDK
// 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);
    }
}
コード例 #2
0
ファイル: assets.cpp プロジェクト: RichardRanft/LoomSDK
// Clears the asset name cache that is built up
// through loom_asset_lock and others
static void loom_asset_clear()
{
    utHashTableIterator<utHashTable<utHashedString, loom_asset_t *> > assetIterator(gAssetHash);
    while (assetIterator.hasMoreElements())
    {
        utHashedString key = assetIterator.peekNextKey();
        lmDelete(NULL, assetIterator.peekNextValue());
        assetIterator.next();
    }
    gAssetHash.clear();
}
コード例 #3
0
ファイル: assets.cpp プロジェクト: RichardRanft/LoomSDK
   bool decRef()
   {
      refCount--;
      
      if(refCount == 0)
      {
         if(dtor)
            dtor(bits);
         else
            lmFree(gAssetAllocator, bits);

         refCount = 0xBAADF00D;
         length = -1;
         bits = NULL;
         
         lmDelete(gAssetAllocator, this);
         return true;
      }
      return false;
   }
コード例 #4
0
ファイル: assets.cpp プロジェクト: RichardRanft/LoomSDK
static void loom_asset_binaryDtor(void *bytes)
{
    lmDelete(NULL, (utByteArray*)bytes);
}
コード例 #5
0
ファイル: main.cpp プロジェクト: Y-way/LoomSDK
void DLLEXPORT assetAgent_run(IdleCallback idleCb, LogCallback logCb, FileChangeCallback changeCb)
{
    loom_log_initialize();
    platform_timeInitialize();
    stringtable_initialize();
    loom_net_initialize();

    // Put best effort towards closing our listen socket when we shut down, to
    // avoid bugs on OSX where the OS won't release it for a while.

#if LOOM_PLATFORM == LOOM_PLATFORM_OSX || LOOM_PLATFORM == LOOM_PLATFORM_LINUX
    atexit(shutdownListenSocket);
    signal(SIGINT, shutdownListenSocketSignalHandler);
#endif

    // Set up mutexes.
    gActiveSocketsMutex = loom_mutex_create();
    gFileScannerLock    = loom_mutex_create();
    gCallbackLock       = loom_mutex_create();

    // Note callbacks.
    gLogCallback        = logCb;
    gFileChangeCallback = changeCb;


    utString *sdkPath = optionGet("sdk");
    if (sdkPath != NULL) TelemetryServer::setClientRootFromSDK(sdkPath->c_str());
    const char *ltcPath = getenv("LoomTelemetry");
    if (ltcPath != NULL) TelemetryServer::setClientRoot(ltcPath);

    if (optionEquals("telemetry", "true")) TelemetryServer::start();



    // Set up the log callback.
    loom_log_addListener(fileWatcherLogListener, NULL);

    lmLogDebug(gAssetAgentLogGroup, "Starting file watcher thread...");
    gFileWatcherThread = loom_thread_start((ThreadFunction)fileWatcherThread, NULL);
    lmLogDebug(gAssetAgentLogGroup, "   o OK!");

    lmLogDebug(gAssetAgentLogGroup, "Starting socket listener thread...");
    gSocketListenerThread = loom_thread_start((ThreadFunction)socketListeningThread, NULL);
    lmLogDebug(gAssetAgentLogGroup, "   o OK!");

    // Loop till it's time to quit.
    while (!gQuitFlag)
    {
        // Serve the idle callback.
        if (idleCb)
        {
            idleCb();
        }

        // And anything in the queue.
        while (CallbackQueueNote *cqn = dequeueCallback())
        {
            if (!cqn)
            {
                break;
            }

            // Issue the call.
            if (cqn->type == QNT_Change)
            {
                gFileChangeCallback(cqn->text.c_str());
            }
            else if (cqn->type == QNT_Log)
            {
                gLogCallback(cqn->text.c_str());
            }
            else
            {
                lmAssert(false, "Unknown callback queue note type.");
            }

            // Clean it up.
            //free((void *)cqn->text);
            lmDelete(NULL, cqn);
        }
        // Pump any remaining socket writes
        loom_net_pump();

        // Poll at about 60hz.
        loom_thread_sleep(16);
    }

    // Clean up the socket.
    shutdownListenSocket();
}
コード例 #6
0
ファイル: main.cpp プロジェクト: Y-way/LoomSDK
// 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;
}
コード例 #7
0
ファイル: l2dDisplayObject.cpp プロジェクト: Y-way/LoomSDK
void DisplayObject::render(lua_State *L) {
    // Disable reentrancy for this function (read: don't cache to texture while caching to a texture)
    if (cacheAsBitmapInProgress) return;

    // Clear and free the cached image if the conditions apply
    if ((!cacheAsBitmap || !cacheAsBitmapValid) && cachedImage != NULL) {
        Quad* quad = static_cast<Quad*>(cachedImage);

        lmAssert(quad != NULL, "Cached image is invalid");

        GFX::Texture::dispose(quad->getNativeTextureID());
        quad->setNativeTextureID(-1);

        lmDelete(NULL, quad);
        cachedImage = NULL;
        cacheAsBitmapValid = false;
    }

    // Cache the contents into an image if the conditions apply
    if (cacheAsBitmap && !cacheAsBitmapValid && cachedImage == NULL) {
        cacheAsBitmapInProgress = true;
        
        // Used for displaying the texture
        Quad* quad = lmNew(NULL) Quad();
        
        // Setup for getmember
        lualoom_pushnative<DisplayObject>(L, this);
        
        // Push function and arguments
        lualoom_getmember(L, -1, "getBounds");
        lualoom_pushnative<DisplayObject>(L, this);
        lua_pushnil(L);
        // Call getBounds
        lua_call(L, 2, 1);
        
        // Returned result
        Loom2D::Rectangle *bounds = (Loom2D::Rectangle*) lualoom_getnativepointer(L, -1);
        cacheAsBitmapOffsetX = bounds->x;
        cacheAsBitmapOffsetY = bounds->y;
        lmscalar fracWidth = bounds->width;
        lmscalar fracHeight = bounds->height;

        // pop bounds Rectangle and the DisplayObject at the top
        lua_pop(L, 1+1);

        if (cacheApplyScale)
        {
            fracWidth *= scaleX;
            fracHeight *= scaleY;
        }

        // Convert to integers for the following math
        int texWidthI = static_cast<int>(ceil(fracWidth));
        int texHeightI = static_cast<int>(ceil(fracHeight));

        // Calculate power of 2 sizes
        if (cacheUseTexturesPot)
        {
            _UT_UTHASHTABLE_POW2(texWidthI);
            _UT_UTHASHTABLE_POW2(texHeightI);
        }

        // Calculate the resulting scale (as a consequence of pow2 sizes)
        // Used for 'trans' matrix
        lmscalar calcScaleX = texWidthI / bounds->width;
        lmscalar calcScaleY = texHeightI / bounds->height;

        // Setup texture
        TextureInfo *tinfo = Texture::initEmptyTexture(texWidthI, texHeightI);
        Texture::clear(tinfo->id, 0x000000, 0);
        tinfo->smoothing = TEXTUREINFO_SMOOTHING_BILINEAR;
        tinfo->wrapU = TEXTUREINFO_WRAP_CLAMP;
        tinfo->wrapV = TEXTUREINFO_WRAP_CLAMP;
        TextureID id = tinfo->id;

        // Setup quad for rendering the texture
        quad->setNativeTextureID(id);
        
        VertexPosColorTex* qv;

        qv = &quad->quadVertices[0];  qv->x =                    0;  qv->y =                     0;  qv->z = 0; qv->abgr = 0xFFFFFFFF; qv->u = 0; qv->v = 0;
        qv = &quad->quadVertices[1];  qv->x = (float)bounds->width;  qv->y =                     0;  qv->z = 0; qv->abgr = 0xFFFFFFFF; qv->u = 1; qv->v = 0;
        qv = &quad->quadVertices[2];  qv->x =                    0;  qv->y = (float)bounds->height;  qv->z = 0; qv->abgr = 0xFFFFFFFF; qv->u = 0; qv->v = 1;
        qv = &quad->quadVertices[3];  qv->x = (float)bounds->width;  qv->y = (float)bounds->height;  qv->z = 0; qv->abgr = 0xFFFFFFFF; qv->u = 1; qv->v = 1;
        quad->setNativeVertexDataInvalid(false);

        lmAssert(Texture::getRenderTarget() == -1, "Unsupported render target state: %d", Texture::getRenderTarget());

        // Set render target to texture
        Texture::setRenderTarget(id);
        
        // Shift the contents down and to the right so that the elements extending
        // past the left and top edges don't get cut off, ignore other existing transforms
        Matrix trans;
        trans.translate(-cacheAsBitmapOffsetX, -cacheAsBitmapOffsetY);

        trans.scale(calcScaleX, calcScaleY);

        // Setup for Graphics::render
        lualoom_pushnative<DisplayObject>(L, this);
        lualoom_pushnative<Matrix>(L, &trans);
        lua_pushnumber(L, 1);

        // Render the contents into the texture
        Graphics::render(L);

        // Pop previous arguments
        lua_pop(L, 3);

        // Restore render target
        Texture::setRenderTarget(-1);

        // Set valid cached state
        cachedImage = quad;
        cacheAsBitmapValid = true;
        cacheAsBitmapInProgress = false;
    }
}