Example #1
0
bool Engine::Initialize(const VariantMap& parameters)
{
    if (initialized_)
        return true;
    
    PROFILE(InitEngine);
    
    // Set headless mode
    headless_ = GetParameter(parameters, "Headless", false).GetBool();
    
    // Register the rest of the subsystems
    if (!headless_)
    {
        context_->RegisterSubsystem(new Graphics(context_));
        context_->RegisterSubsystem(new Renderer(context_));
    }
    else
    {
        // Register graphics library objects explicitly in headless mode to allow them to work without using actual GPU resources
        RegisterGraphicsLibrary(context_);
    }
    
    // In debug mode, check now that all factory created objects can be created without crashing
    #ifdef _DEBUG
    const HashMap<ShortStringHash, SharedPtr<ObjectFactory> >& factories = context_->GetObjectFactories();
    for (HashMap<ShortStringHash, SharedPtr<ObjectFactory> >::ConstIterator i = factories.Begin(); i != factories.End(); ++i)
        SharedPtr<Object> object = i->second_->CreateObject();
    #endif
    
    // Start logging
    Log* log = GetSubsystem<Log>();
    if (log)
    {
        if (HasParameter(parameters, "LogLevel"))
            log->SetLevel(GetParameter(parameters, "LogLevel").GetInt());
        log->SetQuiet(GetParameter(parameters, "LogQuiet", false).GetBool());
        log->Open(GetParameter(parameters, "LogName", "Urho3D.log").GetString());
    }
    
    // Set maximally accurate low res timer
    GetSubsystem<Time>()->SetTimerPeriod(1);
    
    // Configure max FPS
    if (GetParameter(parameters, "FrameLimiter", true) == false)
        SetMaxFps(0);
    
    // Set amount of worker threads according to the available physical CPU cores. Using also hyperthreaded cores results in
    // unpredictable extra synchronization overhead. Also reserve one core for the main thread
    unsigned numThreads = GetParameter(parameters, "WorkerThreads", true).GetBool() ? GetNumPhysicalCPUs() - 1 : 0;
    if (numThreads)
    {
        GetSubsystem<WorkQueue>()->CreateThreads(numThreads);
        
        LOGINFO(ToString("Created %u worker thread%s", numThreads, numThreads > 1 ? "s" : ""));
    }
    
    // Add resource paths
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    FileSystem* fileSystem = GetSubsystem<FileSystem>();
    String exePath = fileSystem->GetProgramDir();
    
    Vector<String> resourcePaths = GetParameter(parameters, "ResourcePaths", "CoreData;Data").GetString().Split(';');
    Vector<String> resourcePackages = GetParameter(parameters, "ResourcePackages").GetString().Split(';');
    
    for (unsigned i = 0; i < resourcePaths.Size(); ++i)
    {
        bool success = false;
        
        // If path is not absolute, prefer to add it as a package if possible
        if (!IsAbsolutePath(resourcePaths[i]))
        {
            String packageName = exePath + resourcePaths[i] + ".pak";
            if (fileSystem->FileExists(packageName))
            {
                SharedPtr<PackageFile> package(new PackageFile(context_));
                if (package->Open(packageName))
                {
                    cache->AddPackageFile(package);
                    success = true;
                }
            }
            
            if (!success)
            {
                String pathName = exePath + resourcePaths[i];
                if (fileSystem->DirExists(pathName))
                    success = cache->AddResourceDir(pathName);
            }
        }
        else
        {
            String pathName = resourcePaths[i];
            if (fileSystem->DirExists(pathName))
                success = cache->AddResourceDir(pathName);
        }
        
        if (!success)
        {
            LOGERROR("Failed to add resource path " + resourcePaths[i]);
            return false;
        }
    }
    
    // Then add specified packages
    for (unsigned i = 0; i < resourcePackages.Size(); ++i)
    {
        bool success = false;
        
        String packageName = exePath + resourcePackages[i];
        if (fileSystem->FileExists(packageName))
        {
            SharedPtr<PackageFile> package(new PackageFile(context_));
            if (package->Open(packageName))
            {
                cache->AddPackageFile(package);
                success = true;
            }
        }
        
        if (!success)
        {
            LOGERROR("Failed to add resource package " + resourcePackages[i]);
            return false;
        }
    }
    

    // Initialize graphics & audio output
    if (!headless_)
    {
        Graphics* graphics = GetSubsystem<Graphics>();
        Renderer* renderer = GetSubsystem<Renderer>();
        
        if (HasParameter(parameters, "ExternalWindow"))
            graphics->SetExternalWindow(GetParameter(parameters, "ExternalWindow").GetPtr());
        graphics->SetForceSM2(GetParameter(parameters, "ForceSM2", false).GetBool());
        graphics->SetWindowTitle(GetParameter(parameters, "WindowTitle", "Urho3D").GetString());
        if (!graphics->SetMode(
            GetParameter(parameters, "WindowWidth", 0).GetInt(),
            GetParameter(parameters, "WindowHeight", 0).GetInt(),
            GetParameter(parameters, "FullScreen", true).GetBool(),
            GetParameter(parameters, "WindowResizable", false).GetBool(),
            GetParameter(parameters, "VSync", false).GetBool(),
            GetParameter(parameters, "TripleBuffer", false).GetBool(),
            GetParameter(parameters, "MultiSample", 1).GetInt()
        ))
            return false;
        
        if (HasParameter(parameters, "RenderPath"))
            renderer->SetDefaultRenderPath(cache->GetResource<XMLFile>(GetParameter(parameters, "RenderPath").GetString()));
        renderer->SetDrawShadows(GetParameter(parameters, "Shadows", true).GetBool());
        if (renderer->GetDrawShadows() && GetParameter(parameters, "LowQualityShadows", false).GetBool())
            renderer->SetShadowQuality(SHADOWQUALITY_LOW_16BIT);
        
        if (GetParameter(parameters, "Sound", true).GetBool())
        {
            GetSubsystem<Audio>()->SetMode(
                GetParameter(parameters, "SoundBuffer", 100).GetInt(),
                GetParameter(parameters, "SoundMixRate", 44100).GetInt(),
                GetParameter(parameters, "SoundStereo", true).GetBool(),
                GetParameter(parameters, "SoundInterpolation", true).GetBool()
            );
        }
    }
    
    // Init FPU state of main thread
    InitFPU();
    
    frameTimer_.Reset();
    
    initialized_ = true;
    return true;
}
Example #2
0
int main(int argc, char** argv)
{
    #ifdef WIN32
    const Vector<String>& arguments = ParseArguments(GetCommandLineW());
    #else
    const Vector<String>& arguments = ParseArguments(argc, argv);
    #endif
    
    bool dumpApiMode = false;
    String outputFile;
    
    if (arguments.Size() < 1)
        ErrorExit("Usage: ScriptCompiler <input file> [resource path for includes]\n"
                  "       ScriptCompiler -dumpapi [output file]");
    else
    {
        if (arguments[0] != "-dumpapi")
            outputFile = arguments[0];
        else
        {
            dumpApiMode = true;
            if (arguments.Size() > 1)
                outputFile = arguments[1];
        }
    }
    
    SharedPtr<Context> context(new Context());
    
    // Note: creating the Engine registers most subsystems which don't require engine initialization
    SharedPtr<Engine> engine(new Engine(context));
    context->RegisterSubsystem(new Script(context));
    
    Log* log = context->GetSubsystem<Log>();
    // Register Log subsystem manually if compiled without logging support
    if (!log)
    {
        context->RegisterSubsystem(new Log(context));
        log = context->GetSubsystem<Log>();
    }
    
    log->SetLevel(LOG_WARNING);
    log->SetTimeStamp(false);
    
    if (!dumpApiMode)
    {
        String path, file, extension;
        SplitPath(outputFile, path, file, extension);
        
        ResourceCache* cache = context->GetSubsystem<ResourceCache>();
        
        // Add resource path to be able to resolve includes
        if (arguments.Size() > 1)
            cache->AddResourceDir(arguments[1]);
        else
            cache->AddResourceDir(cache->GetPreferredResourceDir(path));
        
        if (!file.StartsWith("*"))
            CompileScript(context, outputFile);
        else
        {
            Vector<String> scriptFiles;
            context->GetSubsystem<FileSystem>()->ScanDir(scriptFiles, path, file + extension, SCAN_FILES, false);
            for (unsigned i = 0; i < scriptFiles.Size(); ++i)
                CompileScript(context, path + scriptFiles[i]);
        }
    }
    else
    {
        if (!outputFile.Empty())
        {
            log->SetQuiet(true);
            log->Open(outputFile);
        }
        // If without output file, dump to stdout instead
        context->GetSubsystem<Script>()->DumpAPI();
    }
    
    return EXIT_SUCCESS;
}