LicenseSystem::LicenseSystem(Context* context) :
    Object(context)
    , eulaAgreementConfirmed_(false)

{
    FileSystem* filesystem = GetSubsystem<FileSystem>();

    licenseFilePath_ = filesystem->GetAppPreferencesDir("AtomicEditor", "License");
    licenseFilePath_ = AddTrailingSlash(licenseFilePath_);

    if (!filesystem->DirExists(licenseFilePath_))
    {
        Poco::File dirs(licenseFilePath_.CString());
        dirs.createDirectories();
    }

    licenseCachePath_ = licenseFilePath_;

    licenseCachePath_ += "AtomicLicenseCache";

    licenseFilePath_ += "AtomicLicense";

    eulaAgreementPath_ = filesystem->GetAppPreferencesDir("AtomicEditor", "License");
    eulaAgreementPath_ = AddTrailingSlash(eulaAgreementPath_);
    eulaAgreementPath_ += "EulaConfirmed";

    ResetLicense();
}
    void AtomicGlowApp::Setup()
    {
        IPCClientApp::Setup();

        // AtomicGlow is always headless
        engineParameters_["Headless"] = true;

        FileSystem* filesystem = GetSubsystem<FileSystem>();
        engineParameters_.InsertNew("LogName", filesystem->GetAppPreferencesDir("AtomicEditor", "Logs") + "AtomicGlow.log");

        ToolSystem* tsystem = new ToolSystem(context_);
        context_->RegisterSubsystem(tsystem);

        ToolEnvironment* env = new ToolEnvironment(context_);
        context_->RegisterSubsystem(env);

        String projectPath;

        for (unsigned i = 0; i < arguments_.Size(); ++i)
        {
            if (arguments_[i].Length() > 1)
            {
                String argument = arguments_[i].ToLower();
                String value = i + 1 < arguments_.Size() ? arguments_[i + 1] : String::EMPTY;

                if (argument == "--project" && value.Length())
                {
                    if (GetExtension(value) == ".atomic")
                    {
                        value = GetPath(value);
                    }

                    if (filesystem->DirExists(value))
                    {

                    }
                    else
                    {
                        ErrorExit(ToString("%s project path does not exist", value.CString()));
                    }

                    projectPath = AddTrailingSlash(value);

                }
            }
        }

        if (!env->Initialize())
        {

			ErrorExit("Unable to initialize tool environment from %s");

            return;
        }

        engineParameters_["ResourcePrefixPaths"] = env->GetRootSourceDir() + "/Resources/";
        engineParameters_["ResourcePaths"] = ToString("CoreData;EditorData;%sResources;%sCache", projectPath.CString(), projectPath.CString());


    }
void LicenseSystem::SaveLicense()
{
    FileSystem* filesystem = GetSubsystem<FileSystem>();
    String licenseFilePath = filesystem->GetAppPreferencesDir("AtomicEditor", "License");
    licenseFilePath = AddTrailingSlash(licenseFilePath);

    if (!filesystem->DirExists(licenseFilePath))
    {
        Poco::File dirs(licenseFilePath.CString());
        dirs.createDirectories();
    }

    licenseFilePath += "AtomicLicense";

    SharedPtr<File> file(new File(context_, licenseFilePath, FILE_WRITE));
    file->WriteInt(1); // version
    file->WriteString(key_);

    file->WriteBool(licenseWindows_);
    file->WriteBool(licenseMac_);
    file->WriteBool(licenseAndroid_);
    file->WriteBool(licenseIOS_);
    file->WriteBool(licenseHTML5_);
    file->WriteBool(licenseModule3D_);

    file->Close();

}
 String AEEditorPrefs::GetPreferencesPath()
 {
     FileSystem* fileSystem = GetSubsystem<FileSystem>();
     String path = fileSystem->GetAppPreferencesDir("AtomicEditor", "Preferences");
     path += "prefs.json";
     return path;
 }
void LicenseSystem::Initialize()
{

    FileSystem* filesystem = GetSubsystem<FileSystem>();
    String eulaConfirmedFilePath = filesystem->GetAppPreferencesDir("AtomicEditor", "License");
    eulaConfirmedFilePath = AddTrailingSlash(eulaConfirmedFilePath);
    eulaConfirmedFilePath += "EulaConfirmed";

    eulaAgreementConfirmed_ = filesystem->FileExists(eulaConfirmedFilePath);

    if (!LoadLicense() || !key_.Length() || !eulaAgreementConfirmed_)
    {
        ResetLicense();
        UIModalOps* ops = GetSubsystem<UIModalOps>();

        if (eulaAgreementConfirmed_)
            ops->ShowActivation();
        else
            ops->ShowEulaAgreement();
    }
    else
    {
        RequestServerVerification(key_);
    }
}
bool LicenseSystem::LoadLicense()
{

    ResetLicense();

    FileSystem* filesystem = GetSubsystem<FileSystem>();
    String licenseFilePath = filesystem->GetAppPreferencesDir("AtomicEditor", "License");
    licenseFilePath = AddTrailingSlash(licenseFilePath);
    licenseFilePath += "AtomicLicense";

    if (!filesystem->FileExists(licenseFilePath))
        return false;

    SharedPtr<File> file(new File(context_, licenseFilePath, FILE_READ));

    file->ReadInt(); // version

    String key = file->ReadString();
    if (!ValidateKey(key))
        return false;

    key_ = key;

    licenseWindows_ = file->ReadBool();
    licenseMac_ = file->ReadBool();
    licenseAndroid_ = file->ReadBool();
    licenseIOS_ = file->ReadBool();
    licenseHTML5_ = file->ReadBool();
    licenseModule3D_ = file->ReadBool();

    return true;
}
String AEPreferences::GetPreferencesFullPath()
{
    FileSystem* fs = GetSubsystem<FileSystem>();
    String filepath = fs->GetAppPreferencesDir("AtomicEditor", "Preferences");
    filepath += "prefs.json";
    return filepath;
}
    void ClockworkPlayerApp::Setup()
    {

#ifdef CLOCKWORK_3D
        RegisterEnvironmentLibrary(context_);
#endif

        FileSystem* filesystem = GetSubsystem<FileSystem>();

        engineParameters_["WindowTitle"] = "ClockworkPlayer";

#if (CLOCKWORK_PLATFORM_ANDROID)
        engineParameters_["FullScreen"] = true;
        engineParameters_["ResourcePaths"] = "CoreData;PlayerData;Cache;ClockworkResources";
#elif CLOCKWORK_PLATFORM_WEB
        engineParameters_["FullScreen"] = false;
        engineParameters_["ResourcePaths"] = "ClockworkResources";
        // engineParameters_["WindowWidth"] = 1280;
        // engineParameters_["WindowHeight"] = 720;
#elif CLOCKWORK_PLATFORM_IOS
        engineParameters_["FullScreen"] = false;
        engineParameters_["ResourcePaths"] = "ClockworkResources";
#else
        engineParameters_["FullScreen"] = false;
        engineParameters_["WindowWidth"] = 1280 * .55f;
        engineParameters_["WindowHeight"] = 720 * .55f;
        engineParameters_["ResourcePaths"] = "/Users/josh/Dev/clockwork/ClockworkGameEngineSharp/Resources/CoreData;/Users/josh/Dev/clockwork/ClockworkGameEngineSharp/Resources/PlayerData;/Users/josh/Dev/clockwork/ClockworkExamples/BunnyMark/Resources;/Users/josh/Dev/clockwork/ClockworkExamples/BunnyMark/";
#endif

#if CLOCKWORK_PLATFORM_WINDOWS
        engineParameters_["WindowIcon"] = "Images/ClockworkLogo32.png";
        engineParameters_["ResourcePrefixPath"] = "ClockworkPlayer_Resources";
#elif CLOCKWORK_PLATFORM_ANDROID
        //engineParameters_["ResourcePrefixPath"] = "assets";
#elif CLOCKWORK_PLATFORM_OSX
        engineParameters_["ResourcePrefixPath"] = "../Resources";
#endif

        const Vector<String>& arguments = GetArguments();

        for (unsigned i = 0; i < arguments.Size(); ++i)
        {
            if (arguments[i].Length() > 1)
            {
                String argument = arguments[i].ToLower();
                String value = i + 1 < arguments.Size() ? arguments[i + 1] : String::EMPTY;

                if (argument == "--log-std")
                {
                    SubscribeToEvent(E_LOGMESSAGE, HANDLER(ClockworkPlayerApp, HandleLogMessage));
                }
            }
        }

        // Use the script file name as the base name for the log file
        engineParameters_["LogName"] = filesystem->GetAppPreferencesDir("ClockworkPlayer", "Logs") + "ClockworkPlayer.log";
    }
void AEEditorApp::Setup()
{
    context_->SetEditorContext(true);

    ToolEnvironment* env = new ToolEnvironment(context_);
    context_->RegisterSubsystem(env);

    ToolSystem* system = new ToolSystem(context_);
    context_->RegisterSubsystem(system);

#ifdef ATOMIC_DEV_BUILD

    if (!env->InitFromJSON())
    {
        ErrorExit(ToString("Unable to initialize tool environment from %s", env->GetDevConfigFilename().CString()));
        return;
    }
#else

    env->InitFromPackage();

#endif

    engineParameters_["WindowTitle"] = "AtomicEditor";
    engineParameters_["WindowResizable"] = true;
    engineParameters_["FullScreen"] = false;
    engineParameters_["LogLevel"] = LOG_DEBUG;

    FileSystem* filesystem = GetSubsystem<FileSystem>();
    engineParameters_["LogName"] = filesystem->GetAppPreferencesDir("AtomicEditor", "Logs") + "AtomicEditor.log";

#ifdef ATOMIC_PLATFORM_OSX
    engineParameters_["WindowIcon"] = "Images/AtomicLogo32.png";
#endif

#ifdef ATOMIC_DEV_BUILD
    engineParameters_["ResourcePrefixPath"] = "";
    String ScriptPath = env->GetRootSourceDir() + "Script";
    String resourcePaths = env->GetCoreDataDir() + ";" +  env->GetEditorDataDir() + ";" + ScriptPath;
    engineParameters_["ResourcePaths"] = resourcePaths;
#else

#ifdef ATOMIC_PLATFORM_OSX
    engineParameters_["ResourcePrefixPath"] = "../Resources";
    
#else
	engineParameters_["ResourcePrefixPath"] = filesystem->GetProgramDir() + "Resources";
#endif

	engineParameters_["ResourcePaths"] = "CoreData;EditorData;Script";

#endif // ATOMIC_DEV_BUILD


}
void LicenseSystem::RemoveLicense()
{
    FileSystem* filesystem = GetSubsystem<FileSystem>();

    String licenseFilePath = filesystem->GetAppPreferencesDir("AtomicEditor", "License");
    licenseFilePath = AddTrailingSlash(licenseFilePath);
    licenseFilePath += "AtomicLicense";

    if (filesystem->FileExists(licenseFilePath))
    {
        filesystem->Delete(licenseFilePath);
    }
}
void LicenseSystem::LicenseAgreementConfirmed()
{
    eulaAgreementConfirmed_ = true;

    FileSystem* filesystem = GetSubsystem<FileSystem>();
    String eulaConfirmedFilePath = filesystem->GetAppPreferencesDir("AtomicEditor", "License");
    eulaConfirmedFilePath = AddTrailingSlash(eulaConfirmedFilePath);
    eulaConfirmedFilePath += "EulaConfirmed";

    SharedPtr<File> file(new File(context_, eulaConfirmedFilePath, FILE_WRITE));
    file->WriteInt(1);
    file->Close();

    UIModalOps* ops = GetSubsystem<UIModalOps>();
    ops->ShowActivation();
}
void AEEditorApp::Setup()
{
    context_->SetEditorContext(true);

    AEEditorCommon::Setup();

    ToolEnvironment* env = GetSubsystem<ToolEnvironment>();

    engineParameters_["WindowTitle"] = "AtomicEditor";
    engineParameters_["WindowResizable"] = true;
    engineParameters_["FullScreen"] = false;
    engineParameters_["LogLevel"] = LOG_DEBUG;

    FileSystem* filesystem = GetSubsystem<FileSystem>();
    engineParameters_["LogName"] = filesystem->GetAppPreferencesDir("AtomicEditor", "Logs") + "AtomicEditor.log";

#ifdef ATOMIC_PLATFORM_OSX
    engineParameters_["WindowIcon"] = "Images/AtomicLogo32.png";
#endif

#ifdef ATOMIC_DEV_BUILD
    engineParameters_["ResourcePrefixPath"] = "";
    String resourcePaths = env->GetCoreDataDir() + ";" + env->GetEditorDataDir();
    // for dev builds, add the compile editor scripts from artifacts
    resourcePaths += ";" + env->GetRootSourceDir() + "Artifacts/Build/Resources/EditorData/";
    engineParameters_["ResourcePaths"] = resourcePaths;
#else

#ifdef ATOMIC_PLATFORM_OSX
    engineParameters_["ResourcePrefixPath"] = "../Resources";

#else
    engineParameters_["ResourcePrefixPath"] = filesystem->GetProgramDir() + "Resources";
#endif

    engineParameters_["ResourcePaths"] = "CoreData;EditorData";

#endif // ATOMIC_DEV_BUILD

    ReadPreferences();

}
void AEPlayerApplication::Setup()
{
    AEEditorCommon::Setup();

    // Read the engine configuration
    ReadEngineConfig();

    engine_->SetAutoExit(false);

    engineParameters_.InsertNew("WindowTitle", "AtomicPlayer");

#if (ATOMIC_PLATFORM_ANDROID)
    engineParameters_["FullScreen"] = true;
    engineParameters_["ResourcePaths"] = "CoreData;AtomicResources";
#elif ATOMIC_PLATFORM_WEB
    engineParameters_["FullScreen"] = false;
    engineParameters_["ResourcePaths"] = "AtomicResources";
    // engineParameters_["WindowWidth"] = 1280;
    // engineParameters_["WindowHeight"] = 720;
#elif ATOMIC_PLATFORM_IOS
    engineParameters_["FullScreen"] = false;
    engineParameters_["ResourcePaths"] = "AtomicResources";
#else
    engineParameters_["FullScreen"] = false;
    engineParameters_["WindowWidth"] = 1280;
    engineParameters_["WindowHeight"] = 720;
#endif

    engineParameters_.InsertNew("LogLevel", LOG_DEBUG);

#if ATOMIC_PLATFORM_WINDOWS || ATOMIC_PLATFORM_LINUX
    engineParameters_["WindowIcon"] = "Images/AtomicLogo32.png";
    engineParameters_["ResourcePrefixPath"] = "AtomicPlayer_Resources";
#elif ATOMIC_PLATFORM_ANDROID
    //engineParameters_["ResourcePrefixPath"] = "assets";
#elif ATOMIC_PLATFORM_OSX
    engineParameters_["ResourcePrefixPath"] = "../Resources";
#endif

    FileSystem* filesystem = GetSubsystem<FileSystem>();

    const Vector<String>& arguments = GetArguments();

    for (unsigned i = 0; i < arguments.Size(); ++i)
    {
        if (arguments[i].Length() > 1)
        {
            String argument = arguments[i].ToLower();
            String value = i + 1 < arguments.Size() ? arguments[i + 1] : String::EMPTY;

            if (argument == "--log-std")
            {
                SubscribeToEvent(E_LOGMESSAGE, HANDLER(AEPlayerApplication, HandleLogMessage));
            }
            else if (argument == "--debug")
            {
                debugPlayer_ = true;
            }
            else if (argument == "--project" && value.Length())
            {
                engineParameters_["ResourcePrefixPath"] = "";

                value = AddTrailingSlash(value);

                // check that cache exists
                if (!filesystem->DirExists(value + "Cache"))
                {
                    ErrorExit("Project cache folder does not exist, projects must be loaded into the Atomic Editor at least once before using the --player command line mode");
                    return;
                }

#ifdef ATOMIC_DEV_BUILD

                String resourcePaths = ToString("%s/Resources/CoreData;%s/Resources/PlayerData;%sResources;%s;%sCache",
                         ATOMIC_ROOT_SOURCE_DIR, ATOMIC_ROOT_SOURCE_DIR, value.CString(), value.CString(), value.CString());

#else

#ifdef __APPLE__
                engineParameters_["ResourcePrefixPath"] = "../Resources";
#else
				engineParameters_["ResourcePrefixPath"] = filesystem->GetProgramDir() + "Resources";
#endif

                String resourcePaths = ToString("CoreData;PlayerData;%s/;%s/Resources;%s;%sCache",
                                                              value.CString(), value.CString(), value.CString(), value.CString());
#endif

                LOGINFOF("Adding ResourcePaths: %s", resourcePaths.CString());

                engineParameters_["ResourcePaths"] = resourcePaths;

#ifdef ATOMIC_DOTNET
                NETCore* netCore = GetSubsystem<NETCore>();
                String assemblyLoadPath = GetNativePath(ToString("%sResources/Assemblies/", value.CString()));
                netCore->AddAssemblyLoadPath(assemblyLoadPath);
#endif

            }
            else if (argument == "--windowposx" && value.Length()) 
            {
                engineParameters_["WindowPositionX"] = atoi(value.CString());
            }
            else if (argument == "--windowposy" && value.Length())
            {
                engineParameters_["WindowPositionY"] = atoi(value.CString());
            }
            else if (argument == "--windowwidth" && value.Length())
            {
                engineParameters_["WindowWidth"] = atoi(value.CString());
            }
            else if (argument == "--windowheight" && value.Length())
            {
                engineParameters_["WindowHeight"] = atoi(value.CString());
            }
            else if (argument == "--resizable") 
            {
                engineParameters_["WindowResizable"] = true;
            } 
            else if (argument == "--maximize")
            {
                engineParameters_["WindowMaximized"] = true;
            }
        }
    }

    // Use the script file name as the base name for the log file
    engineParameters_["LogName"] = filesystem->GetAppPreferencesDir("AtomicPlayer", "Logs") + "AtomicPlayer.log";
}
Beispiel #14
0
void Urho3DPlayer::Setup()
{
    FileSystem* filesystem = GetSubsystem<FileSystem>();

    // Read command line from a file if no arguments given. This is primarily intended for mobile platforms.
    // Note that the command file name uses a hardcoded path that does not utilize the resource system
    // properly (including resource path prefix), as the resource system is not yet initialized at this point
    const String commandFileName = filesystem->GetProgramDir() + "Data/CommandLine.txt";
    if (GetArguments().Empty() && filesystem->FileExists(commandFileName))
    {
        SharedPtr<File> commandFile(new File(context_, commandFileName));
        String commandLine = commandFile->ReadLine();
        commandFile->Close();
        ParseArguments(commandLine, false);
        // Reparse engine startup parameters now
        engineParameters_ = Engine::ParseParameters(GetArguments());
    }

    // Check for script file name
    const Vector<String>& arguments = GetArguments();
    String scriptFileName;
    if (arguments.Size() && arguments[0][0] != '-')
        scriptFileName_ = GetInternalPath(arguments[0]);

    // Show usage if not found
    if (scriptFileName_.Empty())
    {
        ErrorExit("Usage: Urho3DPlayer <scriptfile> [options]\n\n"
            "The script file should implement the function void Start() for initializing the "
            "application and subscribing to all necessary events, such as the frame update.\n"
            #ifndef WIN32
            "\nCommand line options:\n"
            "-x <res>     Horizontal resolution\n"
            "-y <res>     Vertical resolution\n"
            "-m <level>   Enable hardware multisampling\n"
            "-v           Enable vertical sync\n"
            "-t           Enable triple buffering\n"
            "-w           Start in windowed mode\n"
            "-s           Enable resizing when in windowed mode\n"
            "-q           Enable quiet mode which does not log to standard output stream\n"
            "-b <length>  Sound buffer length in milliseconds\n"
            "-r <freq>    Sound mixing frequency in Hz\n"
            "-p <paths>   Resource path(s) to use, separated by semicolons\n"
            "-ap <paths>  Autoload resource path(s) to use, seperated by semicolons\n"
            "-log <level> Change the log level, valid 'level' values are 'debug', 'info', 'warning', 'error'\n"
            "-ds <file>   Dump used shader variations to a file for precaching\n"
            "-mq <level>  Material quality level, default 2 (high)\n"
            "-tq <level>  Texture quality level, default 2 (high)\n"
            "-tf <level>  Texture filter mode, default 2 (trilinear)\n"
            "-af <level>  Texture anisotropy level, default 4. Also sets anisotropic filter mode\n"
            "-gl2         Force OpenGL 2 use even if OpenGL 3 is available\n"
            "-flushgpu    Flush GPU command queue each frame. Effective only on Direct3D\n"
            "-borderless  Borderless window mode\n"
            "-headless    Headless mode. No application window will be created\n"
            "-landscape   Use landscape orientations (iOS only, default)\n"
            "-portrait    Use portrait orientations (iOS only)\n"
            "-prepass     Use light pre-pass rendering\n"
            "-deferred    Use deferred rendering\n"
            "-renderpath <name> Use the named renderpath (must enter full resource name)\n"
            "-lqshadows   Use low-quality (1-sample) shadow filtering\n"
            "-noshadows   Disable shadow rendering\n"
            "-nolimit     Disable frame limiter\n"
            "-nothreads   Disable worker threads\n"
            "-nosound     Disable sound output\n"
            "-noip        Disable sound mixing interpolation\n"
            "-touch       Touch emulation on desktop platform\n"
            #endif
        );
    }
    else
    {
        // Use the script file name as the base name for the log file
        engineParameters_["LogName"] = filesystem->GetAppPreferencesDir("urho3d", "logs") + GetFileNameAndExtension(scriptFileName_) + ".log";
    }

    // Construct a search path to find the resource prefix with two entries:
    // The first entry is an empty path which will be substituted with program/bin directory -- this entry is for binary when it is still in build tree
    // The second and third entries are possible relative paths from the installed program/bin directory to the asset directory -- these entries are for binary when it is in the Urho3D SDK installation location
    if (!engineParameters_.Contains("ResourcePrefixPaths"))
        engineParameters_["ResourcePrefixPaths"] = ";../share/Resources;../share/Urho3D/Resources";
}
WebBrowserHost::WebBrowserHost(Context* context) : Object (context)
{

    const Vector<String>& arguments = GetArguments();

#ifdef ATOMIC_PLATFORM_LINUX
    XSetErrorHandler(XErrorHandlerImpl);
    XSetIOErrorHandler(XIOErrorHandlerImpl);

    // Install a signal handler so we clean up after ourselves.
    signal(SIGINT, TerminationSignalHandler);
    signal(SIGTERM, TerminationSignalHandler);

#endif

    // IMPORTANT: See flags being set in implementation of void WebAppBrowser::OnBeforeCommandLineProcessing
    // these include "--enable-media-stream", "--enable-usermedia-screen-capturing", "--off-screen-rendering-enabled", "--transparent-painting-enabled"

#ifdef ATOMIC_PLATFORM_LINUX
    static const char* _argv[2] = { "AtomicWebView", "--disable-setuid-sandbox" };
    CefMainArgs args(2, (char**) &_argv);
#else
    CefMainArgs args;
#endif

    CefSettings settings;
    settings.windowless_rendering_enabled = 1;    

    FileSystem* fs = GetSubsystem<FileSystem>();

    // Set CEF log file to existing log folder if any avoid attempting to write
    // to executable folder, which is likely not writeable

    Log* log = GetSubsystem<Log>();
    if (log && log->GetLogFile())
    {
        const File* logFile = log->GetLogFile();
        String logPath = logFile->GetName ();
        if (logPath.Length())
        {
            String pathName, fileName, ext;
            SplitPath(logPath, pathName, fileName, ext);
            if (pathName.Length())
            {
                pathName = AddTrailingSlash(pathName) + "CEF.log";
                CefString(&settings.log_file).FromASCII(GetNativePath(pathName).CString());
            }
            
        }
        
    }        

    // default background is white, add a setting
    // settings.background_color = 0;

    if (productVersion_.Length())
    {
        CefString(&settings.product_version).FromASCII(productVersion_.CString());
    }

    if (userAgent_.Length())
    {
        CefString(&settings.user_agent).FromASCII(userAgent_.CString());
    }

    String fullPath;

    // If we've specified the absolute path to a root cache folder, use it
    if (rootCacheFolder_.Length() && cacheName_.Length())
    {        
        fullPath = rootCacheFolder_ + "/" + cacheName_;
        CefString(&settings.cache_path).FromASCII(fullPath.CString());
    }
    else
    {
        fullPath = fs->GetAppPreferencesDir(cacheName_.CString(), "WebCache");
    }


    CefString(&settings.cache_path).FromASCII(fullPath.CString());

    settings.remote_debugging_port = debugPort_;

    d_ = new WebBrowserHostPrivate(this);

    // If losing OSX system menu, it means we're calling this
    // before initializing graphics subsystem
    if (!CefInitialize(args, settings, d_->app_, nullptr))
    {
        ATOMIC_LOGERROR("CefInitialize - Error");
    }

    RegisterWebSchemeHandlers(this);

    // Ensure cookie manager is created
    CefCookieManager::GetGlobalManager(nullptr);

    SubscribeToEvent(E_UPDATE, ATOMIC_HANDLER(WebBrowserHost, HandleUpdate));

    instance_ = this;

}
bool AEPreferences::ReadStartupPrefs(Context *context, StartupPreferences& prefs)
{

    FileSystem* fileSystem = context->GetSubsystem<FileSystem>();
    String filepath = fileSystem->GetAppPreferencesDir("AtomicEditor", "Preferences");
    filepath += "prefs.json";

    if (!fileSystem->FileExists(filepath))
        return false;

    SharedPtr<File> file(new File(context, filepath, FILE_READ));

    if (!file->IsOpen())
        return false;

    String json;
    file->ReadText(json);

    if (!json.Length())
        return false;

    rapidjson::Document document;

    if (document.Parse<0>(json.CString()).HasParseError())
    {
        return false;
    }

    bool success = true;

    const Value::Member* imember = document.FindMember("window_pos_x");
    if (imember && imember->value.IsInt())
    {
        prefs.windowPos.x_ = imember->value.GetInt();
    }
    else
    {
        success = false;
    }

    imember = document.FindMember("window_pos_y");
    if (imember && imember->value.IsInt())
    {
        prefs.windowPos.y_ = imember->value.GetInt();
    }
    else
    {
        success = false;
    }

    imember = document.FindMember("window_width");
    if (imember && imember->value.IsInt())
    {
        prefs.windowWidth = imember->value.GetInt();
    }
    else
    {
        success = false;
    }

    imember = document.FindMember("window_height");
    if (imember && imember->value.IsInt())
    {
        prefs.windowHeight = imember->value.GetInt();
    }
    else
    {
        success = false;
    }

    if (prefs.windowHeight < 128 || prefs.windowWidth < 128)
        return false;

    return success;

}