Пример #1
0
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();
}
Пример #2
0
int
main(int argc, char *argv[])
{
#ifdef MSVC_DEBUG_HEAP
    // Get current flag
    int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);

    tmpFlag |= _CRTDBG_ALLOC_MEM_DF;
    tmpFlag |= _CRTDBG_LEAK_CHECK_DF;

    // Set flag to the new value.
    _CrtSetDbgFlag(tmpFlag);
#endif

#ifdef WIN32
    // When on windows, do some workarounds so our console window
    // behaves properly.
    
    // put the program name into argv[0]
    char filename[_MAX_PATH];
    GetModuleFileNameA(NULL, filename, _MAX_PATH);
    argv[0] = filename;

    bool fromRuby = false;

    for (int i = 1; i < argc; i++)
    {
        if (!stricmp(argv[i], "ProcessID") && i + 1 < argc)
        {
            fromRuby = true;

            char *pEnd;  

            long int pid = strtol (argv[i + 1], &pEnd, 10);

            LS::Process::rubyProcessId = pid;

            memmove(argv + i, argv + i + 2, (argc - i - 2)*sizeof(char*));
            argc -= 2;
            i--;
            break;
        }
    }

    LS::Process::consoleAttached = false;
    if (!fromRuby && AttachConsole(ATTACH_PARENT_PROCESS))
    {
        HANDLE consoleHandleOut = GetStdHandle(STD_OUTPUT_HANDLE);
        int fdOut = _open_osfhandle((intptr_t)consoleHandleOut, _O_TEXT);
        FILE *fpOut = _fdopen(fdOut, "w");
        *stdout = *fpOut;
        setvbuf(stdout, NULL, _IONBF, 0);

        //redirect unbuffered STDERR to the console
        HANDLE consoleHandleError = GetStdHandle(STD_ERROR_HANDLE);
        int fdError = _open_osfhandle((intptr_t)consoleHandleError, _O_TEXT);
        FILE *fpError = _fdopen(fdError, "w");
        *stderr = *fpError;
        setvbuf(stderr, NULL, _IONBF, 0);

        LS::Process::consoleAttached = true;
    }
#endif

    // Initialize logging.
    loom_log_initialize();

    LSLuaState::initCommandLine(argc, (const char**) argv);

    /* Enable standard application logging */
    SDL_LogSetAllPriority(SDL_LOG_PRIORITY_INFO);
    SDL_LogSetOutputFunction(sdlLogOutput, NULL);

    SDL_Init(
        SDL_INIT_TIMER |
        SDL_INIT_VIDEO | 
        SDL_INIT_JOYSTICK |
        SDL_INIT_HAPTIC |
        SDL_INIT_GAMECONTROLLER |
        SDL_INIT_EVENTS
    );

    

    int ret;

    
#if LOOM_RENDERER_OPENGLES2
    ret = SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
    lmAssert(ret == 0, "SDL Error: %s", SDL_GetError());
    ret = SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    lmAssert(ret == 0, "SDL Error: %s", SDL_GetError());
#endif
    
    int stencilSize = 1;
    ret = SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilSize);
    lmAssert(ret == 0, "SDL Error: %s", SDL_GetError());
    
    // Set up SDL window.
    if ((gSDLWindow = SDL_CreateWindow(
        "Loom",
        0, 0,
        100,
        100,
        SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN
#if LOOM_PLATFORM == LOOM_PLATFORM_IOS
        | SDL_WINDOW_BORDERLESS
#endif
        | SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI)) == NULL)
    {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateWindow(): %s\n", SDL_GetError());
        exit(0);
    }

    gContext = SDL_GL_CreateContext(gSDLWindow);
    if (!gContext) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GL_CreateContext(): %s\n", SDL_GetError());
        exit(2);
    }

    ret = SDL_GL_SetSwapInterval(-1);
    if (ret != 0) {
        lmLog(coreLogGroup, "Late swap tearing not supported, using vsync");
        SDL_GL_SetSwapInterval(1);
    }

    // And show the window with proper settings.
    SDL_SetWindowPosition(gSDLWindow, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);

    SDL_StopTextInput();

    // Initialize Loom!
    loom_appSetup();    
    supplyEmbeddedAssets();

    /* Main render loop */
    gLoomExecutionDone = 0;

    /* Display SDL version */
    SDL_version compiled;
    SDL_version linked;

    SDL_VERSION(&compiled);
    SDL_GetVersion(&linked);

    lmLogDebug(coreLogGroup, "Compiled with SDL version %d.%d.%d and linking against SDL version %d.%d.%d ...", compiled.major, compiled.minor, compiled.patch, linked.major, linked.minor, linked.patch);

    /* Game Controller */
    // Enable controller events
    SDL_GameControllerEventState(SDL_ENABLE);

    //Open all connected game controllers
    LoomGameController::openAll();
    
#ifdef __EMSCRIPTEN__
    emscripten_set_main_loop(loop, 0, 1);
#else
    while (!gLoomExecutionDone) loop();
#endif

    //Close all opened game controllers before closing application
    LoomGameController::closeAll();
    loom_appShutdown();
    
#ifdef WIN32
    LS::Process::cleanupConsole();
#endif

    exit(0);
    return 0; /* to prevent compiler warning */
}