bool BuildWindows::BuildManaged(const String& buildPath)
{
    ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
    ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
    FileSystem* fileSystem = GetSubsystem<FileSystem>();
    Project* project = toolSystem->GetProject();
    ProjectSettings* settings = project->GetProjectSettings();

    String projectPath = project->GetProjectPath();

#ifdef ATOMIC_DEBUG
    String config = "Debug";
#else
    String config = "Release";
#endif

    String managedBins = projectPath + ToString("AtomicNET/%s/Bin/Desktop/", config.CString());
    String managedExe = managedBins + settings->GetName() + ".exe";

    if (!fileSystem->FileExists(managedExe))
    {
        FailBuild(ToString("Error building managed project, please compile the %s binary %s before building", config.CString(), managedExe.CString()));
        return false;
    }

    StringVector results;
    StringVector filtered;

    fileSystem->ScanDir(results, managedBins, "", SCAN_FILES, false);

    StringVector filterList;

    StringVector::Iterator itr = results.Begin();
    while (itr != results.End())
    {
        unsigned i;
        for (i = 0; i < filterList.Size(); i++)
        {
            if (itr->Contains(filterList[i]))
                break;
        }

        if (i == filterList.Size())
            filtered.Push(*itr);

        itr++;
    }

    for (unsigned i = 0; i < filtered.Size(); i++)
    {
        String filename = filtered[i];

        if (!BuildCopyFile(managedBins + filename, buildPath_ + "/" + filename))
            return false;

    }

    return true;

}
BuildAndroid::BuildAndroid(Context* context, Project* project) : BuildBase(context, project, PLATFORMID_ANDROID)
{
    ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
    // this cast isn't great
    platformAndroid_ = (PlatformAndroid*) toolSystem->GetPlatformByID(PLATFORMID_ANDROID);

}
bool AndroidProjectGenerator::GenerateProjectProperties()
{
    ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
    Project* project = toolSystem->GetProject();
    AndroidBuildSettings* settings = project->GetBuildSettings()->GetAndroidBuildSettings();

    String apiString = settings->GetSDKVersion();

    if (!apiString.Length())
    {
        errorText_ = "Invalid Android API level, Press Refresh and select a valid level.";
        return false;
    }


    String props;
    props.AppendWithFormat("target=%s", apiString.CString());

    File file(context_, buildPath_ + "/project.properties", FILE_WRITE);

    if (!file.IsOpen())
    {
        errorText_ = "Project generator unable to open file project.properties in " + buildPath_;
        return false;
    }
    file.Write(props.CString(), props.Length());

    return true;

}
void PlatformAddCmd::Run()
{
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
    Project* project = tsystem->GetProject();

    Platform* platform = tsystem->GetPlatformByName(platformToAdd_);

    if (!platform)
    {
        Error(ToString("Unknown platform: %s", platformToAdd_.CString()));
        return;
    }

    if (project->ContainsPlatform(platform->GetPlatformID()))
    {
        Error(ToString("Project already contains platform: %s", platformToAdd_.CString()));
        return;
    }

    LOGINFOF("Adding platform: %s", platformToAdd_.CString());

    project->AddPlatform(platform->GetPlatformID());

    Finished();
}
Example #5
0
void PlayCmd::Run()
{
    LOGINFOF("Playing project");

    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
    ToolEnvironment* env = GetSubsystem<ToolCore::ToolEnvironment>();
    Project* project = tsystem->GetProject();
    const String& editorBinary = env->GetEditorBinary();

    Vector<String> paths;
    paths.Push(env->GetCoreDataDir());
    paths.Push(env->GetPlayerDataDir());
    paths.Push(project->GetResourcePath());

    // fixme: this is for loading from cache
    paths.Push(project->GetProjectPath());
    paths.Push(project->GetProjectPath() + "Cache");

    String resourcePaths;
    resourcePaths.Join(paths, "!");

    Vector<String> vargs;

    String args = ToString("--player --project \"%s\"", AddTrailingSlash(project->GetProjectPath()).CString());

    vargs = args.Split(' ');
    //vargs.Insert(0, "--player");

    // TODO: use IPC (maybe before this set log location/access the log and output it, we need access to errors)
    LaunchPlayerProcess(editorBinary, vargs, "");

    Finished();

}
static int AssetDatabase_GetAssetsByImporterType(duk_context* ctx)
{
    JSVM* vm = JSVM::GetJSVM(ctx);
    ToolSystem* ts = vm->GetSubsystem<ToolSystem>();
    AssetDatabase* db = vm->GetSubsystem<AssetDatabase>();
    Project* project = ts->GetProject();

    StringHash type = duk_require_string(ctx, 0);
    String resourceType = duk_require_string(ctx, 1);

    duk_push_array(ctx);

    if (!project)
        return 1;

    PODVector<Asset*> assets;
    db->GetAssetsByImporterType(type, resourceType, assets);

    for(unsigned i = 0; i < assets.Size(); i++)
    {
        js_push_class_object_instance(ctx, assets[i], 0);
        duk_put_prop_index(ctx, -2, i);
    }

    return 1;
}
void BuildAndroid::RunADBStartActivity()
{

    SubprocessSystem* subs = GetSubsystem<SubprocessSystem>();
    String adbCommand = platformAndroid_->GetADBCommand();

    ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
    Project* project = toolSystem->GetProject();
    AndroidBuildSettings* settings = project->GetBuildSettings()->GetAndroidBuildSettings();

    String stringArgs;
    const char* cpackage = settings->GetPackageName().CString();
    stringArgs.AppendWithFormat("shell am start -n %s/%s.AtomicGameEngine",cpackage, cpackage);

    Vector<String> args = stringArgs.Split(' ');

    currentBuildPhase_ = ADBStartActivity;
    Subprocess* subprocess = subs->Launch(adbCommand, args, buildPath_);
    if (!subprocess)
    {
        FailBuild("StartActivity operation did not launch successfully.");
        return;
    }

    VariantMap buildOutput;
    buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Starting Android Activity</color>\n\n";
    SendEvent(E_BUILDOUTPUT, buildOutput);

    SubscribeToEvent(subprocess, E_SUBPROCESSCOMPLETE, ATOMIC_HANDLER(BuildAndroid, HandleADBStartActivityComplete));
    SubscribeToEvent(subprocess, E_SUBPROCESSOUTPUT, ATOMIC_HANDLER(BuildBase, HandleSubprocessOutputEvent));

}
bool CubemapGenerator::InitPaths()
{

    String scenePath = sceneEditor_->GetFullPath();

    String pathName;
    String fileName;
    String ext;

    SplitPath(scenePath, pathName, fileName, ext);

    outputPathAbsolute_ = pathName + "Cubemaps/" + fileName + "/";

    FileSystem* fileSystem = GetSubsystem<FileSystem>();

    if (!fileSystem->DirExists(outputPathAbsolute_))
    {
        if (!fileSystem->CreateDirs(pathName,  "Cubemaps/" + fileName + "/"))
        {
            LOGERRORF("CubemapGenerator::InitRender - Unable to create path: %s", outputPathAbsolute_.CString());
            return false;
        }
    }

    // TODO: There should be a better way of getting the resource path
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
    Project* project = tsystem->GetProject();

    resourcePath_ = outputPathAbsolute_;
    resourcePath_.Replace(project->GetResourcePath(), "");
    resourcePath_ = AddTrailingSlash(resourcePath_);

    return true;

}
bool AndroidProjectGenerator::GenerateAndroidManifest()
{
    ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
    Project* project = toolSystem->GetProject();
    AndroidBuildSettings* settings = project->GetBuildSettings()->GetAndroidBuildSettings();

    String package = settings->GetPackageName();


    if (!package.Length())
    {
        errorText_ = "Invalid Package Name";
        return false;
    }

    // TODO: from settings
    String activityName = "AtomicGameEngine";
    if (!activityName.Length())
    {
        errorText_ = "Invalid Activity Name";
        return false;
    }

    String manifest  = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    manifest += "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n";
    manifest.AppendWithFormat("package=\"%s\"\n", package.CString());
    manifest += "android:versionCode=\"1\"\n";
    manifest += "android:versionName=\"1.0\">\n";

    manifest += "<uses-permission android:name=\"android.permission.INTERNET\" />\n";
    manifest += "<uses-feature android:glEsVersion=\"0x00020000\" />\n";
    manifest += "<uses-sdk android:targetSdkVersion=\"12\" android:minSdkVersion=\"10\" />\n";

    manifest += "<application android:label=\"@string/app_name\" android:icon=\"@drawable/icon\">\n";
    manifest.AppendWithFormat("<activity android:name=\".%s\"\n", activityName.CString());

    manifest += "android:label=\"@string/app_name\"\n";
    manifest += "android:theme=\"@android:style/Theme.NoTitleBar.Fullscreen\"\n";
    manifest += "android:configChanges=\"keyboardHidden|orientation\"\n";
    manifest += "android:screenOrientation=\"landscape\">\n";
    manifest += "<intent-filter>\n";
    manifest += "<action android:name=\"android.intent.action.MAIN\" />\n";
    manifest += "<category android:name=\"android.intent.category.LAUNCHER\" />\n";
    manifest += "</intent-filter>\n";
    manifest += "</activity>\n";
    manifest += "</application>\n";
    manifest += "</manifest>\n";

    File file(context_, buildPath_ + "/AndroidManifest.xml", FILE_WRITE);

    if (!file.IsOpen())
        return false;

    file.Write(manifest.CString(), manifest.Length());

    return true;

}
bool EditorMode::PlayProject(String addArgs, bool debug)
{
    ToolEnvironment* env = GetSubsystem<ToolEnvironment>();
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();

    const String& editorBinary = env->GetEditorBinary();

    Project* project = tsystem->GetProject();

    if (!project)
        return false;

    Vector<String> paths;
    paths.Push(env->GetCoreDataDir());
    paths.Push(env->GetPlayerDataDir());
    paths.Push(project->GetResourcePath());

    // fixme: this is for loading from cache
    paths.Push(project->GetProjectPath());
    paths.Push(project->GetProjectPath() + "Cache");

    String resourcePaths;
    resourcePaths.Join(paths, "!");

    Vector<String> vargs;

    String args = ToString("--player --project \"%s\"", AddTrailingSlash(project->GetProjectPath()).CString());

    vargs = args.Split(' ');

    if (debug)
        vargs.Insert(0, "--debug");

    if (addArgs.Length() > 0)
        vargs.Insert(0, addArgs.Split(' '));

    String dump;
    dump.Join(vargs, " ");
    LOGINFOF("Launching Broker %s %s", editorBinary.CString(), dump.CString());

    IPC* ipc = GetSubsystem<IPC>();
    playerBroker_ = ipc->SpawnWorker(editorBinary, vargs);

    if (playerBroker_)
    {
        SubscribeToEvent(playerBroker_, E_IPCJSERROR, HANDLER(EditorMode, HandleIPCJSError));
        SubscribeToEvent(playerBroker_, E_IPCWORKEREXIT, HANDLER(EditorMode, HandleIPCWorkerExit));
        SubscribeToEvent(playerBroker_, E_IPCWORKERLOG, HANDLER(EditorMode, HandleIPCWorkerLog));
    }

    return playerBroker_.NotNull();

}
bool AndroidProjectGenerator::GenerateActivitySource()
{
    ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
    Project* project = toolSystem->GetProject();
    AndroidBuildSettings* settings = project->GetBuildSettings()->GetAndroidBuildSettings();

    String packageName = settings->GetPackageName();

    if (!packageName.Length())
    {
        errorText_ = "Invalid App Package name. The general naming convention is com.company.appname";
        return false;
    }

    Vector<String> elements = settings->GetPackageName().Split('.');
    String path;
    path.Join(elements, "/");

    path = buildPath_ + "/src/" + path;

    Poco::File dirs(path.CString());
    dirs.createDirectories();

    if (!dirs.exists())
    {
        errorText_ = "Project generator unable to create dirs " + path;
        return false;
    }

    String source;
    source.AppendWithFormat("package %s;\n", packageName.CString());

    source += "import org.libsdl.app.SDLActivity;\n";

    source += "public class AtomicGameEngine extends SDLActivity {\n";

    source += "}\n";

    File file(context_, path + "/AtomicGameEngine.java", FILE_WRITE);

    if (!file.IsOpen())
    {
        errorText_ = "Project generator unable to open file " + path + "/AtomicGameEngine.java";
        return false;
    }
    file.Write(source.CString(), source.Length());

    return true;

}
bool AndroidProjectGenerator::GenerateStringXML()
{
    FileSystem* fs = GetSubsystem<FileSystem>();
    ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
    Project* project = toolSystem->GetProject();
    AndroidBuildSettings* settings = project->GetBuildSettings()->GetAndroidBuildSettings();

    String appName = settings->GetAppName();

    if (!appName.Length())
    {
        errorText_ = "Invalid App Name, select the App Name in Build Settings.";
        return false;
    }

    String strings  = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";

    strings += "<resources>\n";

    strings.AppendWithFormat("<string name=\"app_name\">%s</string>\n", appName.CString());

    strings += "</resources>\n";
    
    // Create res/values if it doesn't exist
    if (!fs->DirExists(buildPath_ + "/res/values"))
    {
        fs->CreateDirsRecursive(buildPath_ + "/res/values");
    }
    
    // Check that we successfully created it
    if (!fs->DirExists(buildPath_ + "/res/values"))
    {
        errorText_ = "Unable to create directory: " + buildPath_ + "/res/values";
        return false;
    }
    
    File file(context_, buildPath_ + "/res/values/strings.xml", FILE_WRITE);

    if (!file.IsOpen())
    {
        errorText_ = "Unable to write: " + buildPath_ + "/res/values/strings.xml";
        return false;
    }

    file.Write(strings.CString(), strings.Length());

    return true;

}
Example #13
0
void BuildMac::Initialize()
{
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
    Project* project = tsystem->GetProject();

    String dataPath = tsystem->GetDataPath();
    String projectResources = project->GetResourcePath();
    String coreDataFolder = dataPath + "CoreData/";

    AddResourceDir(coreDataFolder);
    AddResourceDir(projectResources);

    BuildResourceEntries();

}
bool AndroidProjectGenerator::CopyUserIcons()
{
    FileSystem* fileSystem = GetSubsystem<FileSystem>();
    ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
    Project* project = toolSystem->GetProject();
    AndroidBuildSettings* settings = project->GetBuildSettings()->GetAndroidBuildSettings();

    String userIconPath = settings->GetIconPath();
    if (!fileSystem->DirExists(userIconPath))               // dont do anything if there is no path defined.
        return true;
            
    String userIconDir = userIconPath + "/drawable";        // 1st target dir 
    String userIconFile = userIconDir + "/logo_large.png";  // 1st target file
    String destDir = buildPath_ + "/res/drawable";          // where it should be in the build
    if ( fileSystem->FileExists (userIconFile) )            // is there a file there?
    {
        if ( !buildBase_->BuildCopyFile ( userIconFile, destDir + "/logo_large.png" ))
            return false;
    }

    userIconDir = userIconPath + "/drawable-ldpi"; 
    userIconFile = userIconDir + "/icon.png"; 
    destDir = buildPath_ + "/res/drawable-ldpi";
    if ( fileSystem->FileExists (userIconFile) )
    {
        if ( !buildBase_->BuildCopyFile ( userIconFile, destDir + "/icon.png"))
            return false;
    } 

    userIconDir = userIconPath + "/drawable-mdpi"; 
    userIconFile = userIconDir + "/icon.png"; 
    destDir = buildPath_ + "/res/drawable-mdpi";
    {
        if ( !buildBase_->BuildCopyFile ( userIconFile, destDir + "/icon.png" ))
            return false;
    } 

    userIconDir = userIconPath + "/drawable-hdpi"; 
    userIconFile = userIconDir + "/icon.png"; 
    destDir = buildPath_ + "/res/drawable-hdpi";
    if ( fileSystem->FileExists (userIconFile) )
    {
        if ( !buildBase_->BuildCopyFile ( userIconFile, destDir + "/icon.png" ))
            return false;
    }

    return true;
}
Example #15
0
void BuildMac::Build(const String& buildPath)
{
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();

    buildPath_ = AddTrailingSlash(buildPath) + GetBuildSubfolder();

    Initialize();

    BuildSystem* buildSystem = GetSubsystem<BuildSystem>();

    FileSystem* fileSystem = GetSubsystem<FileSystem>();
    if (fileSystem->DirExists(buildPath_))
        fileSystem->RemoveDir(buildPath_, true);

    String dataPath = tsystem->GetDataPath();

    String appSrcPath = dataPath + "Deployment/MacOS/AtomicPlayer.app";

    fileSystem->CreateDir(buildPath_);

    buildPath_ += "/AtomicPlayer.app";

    fileSystem->CreateDir(buildPath_);

    fileSystem->CreateDir(buildPath_ + "/Contents");
    fileSystem->CreateDir(buildPath_ + "/Contents/MacOS");
    fileSystem->CreateDir(buildPath_ + "/Contents/Resources");

    String resourcePackagePath = buildPath_ + "/Contents/Resources/AtomicResources.pak";
    GenerateResourcePackage(resourcePackagePath);

    fileSystem->Copy(appSrcPath + "/Contents/Resources/Atomic.icns", buildPath_ + "/Contents/Resources/Atomic.icns");

    fileSystem->Copy(appSrcPath + "/Contents/Info.plist", buildPath_ + "/Contents/Info.plist");
    fileSystem->Copy(appSrcPath + "/Contents/MacOS/AtomicPlayer", buildPath_ + "/Contents/MacOS/AtomicPlayer");

#ifdef ATOMIC_PLATFORM_OSX
    Vector<String> args;
    args.Push("+x");
    args.Push(buildPath_ + "/Contents/MacOS/AtomicPlayer");
    fileSystem->SystemRun("chmod", args);
#endif

    buildPath_ = buildPath + "/Mac-Build";    
    buildSystem->BuildComplete(PLATFORMID_MAC, buildPath_);

}
Example #16
0
bool Project::LoadUserPrefs()
{
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();

    String path = GetProjectPath() + "UserPrefs.json";

    userPrefs_->Load(path);

    // If we're in CLI mode, the Build folder is always relative to project
    if (tsystem->IsCLI())
    {
        String path = GetPath(projectFilePath_) + "Build";
        userPrefs_->SetLastBuildPath(path);
    }

    return true;
}
void BuildMac::Initialize()
{
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();

    Project* project = tsystem->GetProject();

    Vector<String> defaultResourcePaths;
    GetDefaultResourcePaths(defaultResourcePaths);
    String projectResources = project->GetResourcePath();

    for (unsigned i = 0; i < defaultResourcePaths.Size(); i++)
    {
        AddResourceDir(defaultResourcePaths[i]);
    }

    AddResourceDir(projectResources);

    BuildResourceEntries();

}
void ImportCmd::Run()
{
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
    Project* project = tsystem->GetProject();
    String resourcePath = project->GetResourcePath();

    String ext = GetExtension(assetFilename_);

    if (ext == ".json")
    {
        Poco::File file(assetFilename_.CString());

        if (!file.exists())
        {
            Error(ToString("JSON source scene does not exist: %s", assetFilename_.CString()));
            return;
        }

        LOGRAWF("Importing JSON: %s", assetFilename_.CString());

        SharedPtr<JSONSceneImporter> jimporter;
        jimporter = new JSONSceneImporter(context_);
        jimporter->Import(assetFilename_);

        SharedPtr<JSONSceneProcess> sceneProcess;
        sceneProcess = new JSONSceneProcess(context_, jimporter);
        sceneProcess->Process(resourcePath);
        sceneProcess->Write();
    }
    else
    {
        SharedPtr<OpenAssetImporter> importer(new OpenAssetImporter(context_));
        if (importer->Load(assetFilename_))
        {
            importer->ExportModel("/Users/josh/Desktop/ExportedModel.mdl");
        }

    }

    Finished();
}
void BuildWindows::Initialize()
{
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();

    Project* project = tsystem->GetProject();

    Vector<String> defaultResourcePaths;
    GetDefaultResourcePaths(defaultResourcePaths);
    String projectResources = project->GetResourcePath();

    for (unsigned i = 0; i < defaultResourcePaths.Size(); i++)
    {
        AddResourceDir(defaultResourcePaths[i]);
    }

    // TODO: smart filtering of cache
    AddResourceDir(project->GetProjectPath() + "Cache/");
    AddResourceDir(projectResources);

    BuildResourceEntries();

}
void BuildWindows::Initialize()
{
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
    Project* project = tsystem->GetProject();

    Vector<String> defaultResourcePaths;
    GetDefaultResourcePaths(defaultResourcePaths);

    for (unsigned i = 0; i < defaultResourcePaths.Size(); i++)
    {
        AddResourceDir(defaultResourcePaths[i]);
    }
    BuildDefaultResourceEntries();

    // Include the project resources and cache separately
    AddProjectResourceDir(project->GetResourcePath());
    AssetDatabase* db = GetSubsystem<AssetDatabase>();
    String cachePath = db->GetCachePath();
    AddProjectResourceDir(cachePath);

    BuildProjectResourceEntries();
}
Example #21
0
void BuildCmd::Run()
{
    ATOMIC_LOGINFOF("Building project for: %s", buildPlatform_.CString());

    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
    Project* project = tsystem->GetProject();

    Platform* platform = NULL;

    platform = tsystem->GetPlatformByName(buildPlatform_);

    if (!platform)
    {
        Error(ToString("Unknown build platform: %s", buildPlatform_.CString()));
        return;
    }

    // create the build
    BuildBase* buildBase = platform->NewBuild(project);
    if (!assetsBuildTag_.Empty())
    {
        buildBase->SetAssetBuildTag(assetsBuildTag_);
    }
    buildBase->SetAutoLog(autoLog_);

    // add it to the build system
    BuildSystem* buildSystem = GetSubsystem<BuildSystem>();

    buildSystem->QueueBuild(buildBase);

    SubscribeToEvent(E_BUILDCOMPLETE, ATOMIC_HANDLER(BuildCmd, HandleBuildComplete));

    // TODO: parallel/serial builds
    buildSystem->StartNextBuild();

}
void BuildAndroid::Initialize()
{
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
    Project* project = tsystem->GetProject();

    Vector<String> defaultResourcePaths;
    GetDefaultResourcePaths(defaultResourcePaths);
    

    for (unsigned i = 0; i < defaultResourcePaths.Size(); i++)
    {
        AddResourceDir(defaultResourcePaths[i]);
    }
    BuildDefaultResourceEntries();

    // TODO: smart filtering of cache
    String projectResources = project->GetResourcePath();
    AddProjectResourceDir(projectResources);
    AssetDatabase* db = GetSubsystem<AssetDatabase>();
    String cachePath = db->GetCachePath();
    AddProjectResourceDir(cachePath);

    BuildProjectResourceEntries();
}
void BuildWindows::Build(const String& buildPath)
{
    BuildSystem* buildSystem = GetSubsystem<BuildSystem>();
    FileSystem* fileSystem = GetSubsystem<FileSystem>();
    ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
    Project* project = tsystem->GetProject();

    buildPath_ = AddTrailingSlash(buildPath);

    if (!resourcesOnly_)
        buildPath_ += GetBuildSubfolder();

    BuildLog("Starting Windows Deployment");

    Initialize();

    if (!resourcesOnly_ && !BuildClean(buildPath_))
        return;

    String rootSourceDir = tenv->GetRootSourceDir();

    if (!BuildCreateDirectory(buildPath_))
        return;

    if (!resourcesOnly_ && !BuildCreateDirectory(buildPath_ + "/AtomicPlayer_Resources"))
        return;

    String resourcePackagePath = buildPath_ + "/AtomicPlayer_Resources/AtomicResources" + PAK_EXTENSION;

    if (resourcesOnly_)
    {
        resourcePackagePath = buildPath_ + "/AtomicResources" + PAK_EXTENSION;
    }

    GenerateResourcePackage(resourcePackagePath);

    if (buildFailed_)
        return;

    if (resourcesOnly_)
        return;

    if (!BuildCreateDirectory(buildPath_ + "/Settings"))
        return;

    String engineJSON(GetSettingsDirectory() + "/Engine.json");

    if (fileSystem->FileExists(engineJSON))
    {
        if (!BuildCopyFile(engineJSON, buildPath_ + "/Settings/Engine.json"))
            return;
    }

    // TODO: Set project as managed and don't key off project assembly

    if (fileSystem->FileExists(project->GetResourcePath() + project->GetProjectSettings()->GetName() + ".dll"))
    {
        if (!BuildManaged(buildPath))
            return;
    }
    else
    {
        BuildNative(buildPath);
    }

    BuildLog("Windows Deployment Complete");

    buildSystem->BuildComplete(PLATFORMID_WINDOWS, buildPath_);

}
void BuildWindows::BuildAtomicNET()
{
    // AtomicNET

    FileSystem* fileSystem = GetSubsystem<FileSystem>();
    ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
    Project* project = tsystem->GetProject();
    String projectResources = project->GetResourcePath();

    String assembliesPath = projectResources + "Assemblies/";

    // if no assemblies path, no need to install AtomicNET
    if (!fileSystem->DirExists(assembliesPath))
        return;

    Vector<String> results;
    fileSystem->ScanDir(results, assembliesPath, "*.dll", SCAN_FILES, true);

    // if no assembiles in Assemblies path, no need to install AtomicNET
    if (!results.Size())
        return;

    BuildLog("Building AtomicNET");

    fileSystem->CreateDir(buildPath_ + "/AtomicPlayer_Resources/AtomicNET");
    fileSystem->CreateDir(buildPath_ + "/AtomicPlayer_Resources/AtomicNET/Atomic");
    fileSystem->CreateDir(buildPath_ + "/AtomicPlayer_Resources/AtomicNET/Atomic/Assemblies");

    fileSystem->CopyDir(tenv->GetNETCoreCLRAbsPath(), buildPath_ + "/AtomicPlayer_Resources/AtomicNET/CoreCLR");
    fileSystem->CopyDir(tenv->GetNETTPAPaths(), buildPath_ + "/AtomicPlayer_Resources/AtomicNET/Atomic/TPA");

    // Atomic Assemblies

    const String& assemblyLoadPaths = tenv->GetNETAssemblyLoadPaths();
    Vector<String> paths = assemblyLoadPaths.Split(';');

    for (unsigned i = 0; i < paths.Size(); i++)
    {
        Vector<String> loadResults;
        fileSystem->ScanDir(loadResults, paths[i], "*.dll", SCAN_FILES, true);

        for (unsigned j = 0; j < loadResults.Size(); j++)
        {
            String pathName, fileName, ext;
            SplitPath(loadResults[j], pathName, fileName, ext);

            if (fileName != "AtomicNETEngine")
                continue;

            fileSystem->Copy(paths[i] + "/" + loadResults[j], ToString("%s/AtomicPlayer_Resources/AtomicNET/Atomic/Assemblies/%s.dll", buildPath_.CString(), fileName.CString()));
        }

    }

    // Project assemblied
    for (unsigned i = 0; i < results.Size(); i++)
    {
        String pathName, fileName, ext;
        SplitPath(results[i], pathName, fileName, ext);
        fileSystem->Copy(assembliesPath + results[i], ToString("%s/AtomicPlayer_Resources/AtomicNET/Atomic/Assemblies/%s.dll", buildPath_.CString(), fileName.CString()));
    }



}
void BuildAndroid::Build(const String& buildPath)
{
    ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
    Project* project = tsystem->GetProject();

    buildPath_ = AddTrailingSlash(buildPath) + GetBuildSubfolder();

    Initialize();
 
    if (!BuildClean(buildPath_))
        return;

    //generate manifest file
    String manifest;
    for (unsigned i = 0; i < resourceEntries_.Size(); i++)
    {
        BuildResourceEntry* entry = resourceEntries_[i];
        manifest += entry->packagePath_;
        if ( i != resourceEntries_.Size() - 1)
            manifest += ";";
    }

    String buildSourceDir = tenv->GetToolDataDir();

    String androidProject = buildSourceDir + "Deployment/Android";

    // Copy the base android project
    FileSystem* fileSystem = GetSubsystem<FileSystem>();
    if( !BuildCopyDir(androidProject, buildPath_))
        return;

    Vector<String> defaultResourcePaths;
    GetDefaultResourcePaths(defaultResourcePaths);
    String projectResources = project->GetResourcePath();

    for (unsigned i = 0; i < defaultResourcePaths.Size(); i++)
    {
        if ( !BuildCopyDir(defaultResourcePaths[i], buildPath_ + "/assets/" + GetFileName(RemoveTrailingSlash(defaultResourcePaths[i]))))
            return;
    }

    if( !BuildCopyDir(project->GetProjectPath() + "Cache/", buildPath_ + "/assets/Cache"))
        return;
    if( !BuildCopyDir(projectResources, buildPath_ + "/assets/AtomicResources"))
        return;

    // write the manifest
    SharedPtr<File> mfile(new File(context_, buildPath_ + "/assets/AtomicManifest", FILE_WRITE));
    mfile->WriteString(manifest);
    mfile->Close();

    //check for Deployment/Android/libs/armeabi-v7a/libAtomicPlayer.so
    if ( !fileSystem->FileExists(androidProject + "/libs/armeabi-v7a/libAtomicPlayer.so")  )
    {
        FailBuild( "The file libAtomicPlayer.so is not found. This is required for APK generation." );
        return;
    }

    AndroidProjectGenerator gen(context_, this);
    gen.SetBuildPath(buildPath_);

    if (!gen.Generate())
    {
        FailBuild(gen.GetErrorText());
        return;
    }

    RunAntDebug();

}
bool EditorMode::PlayProject(String addArgs, bool debug)
{
    FileSystem* fileSystem = GetSubsystem<FileSystem>();
    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
    Project* project = tsystem->GetProject();

    if (!project)
        return false;

    ToolEnvironment* env = GetSubsystem<ToolEnvironment>();

    String playerBinary = env->GetEditorBinary();

    // TODO: We need to configure project as managed
    bool managed = false;
    if (fileSystem->FileExists(project->GetResourcePath() + "AtomicProject.dll"))
    {
        managed = true;
        playerBinary = env->GetAtomicNETManagedIPCPlayerBinary();
    }


    Vector<String> paths;
    paths.Push(env->GetCoreDataDir());
    paths.Push(env->GetPlayerDataDir());
    paths.Push(project->GetResourcePath());

    // fixme: this is for loading from cache
    paths.Push(project->GetProjectPath());
    paths.Push(project->GetProjectPath() + "Cache");

    String resourcePaths;
    resourcePaths.Join(paths, "!");

    Vector<String> vargs;

    String args = ToString("--player --project \"%s\"", AddTrailingSlash(project->GetProjectPath()).CString());

    vargs = args.Split(' ');

    if (managed)
    {            
        vargs.Insert(0, ToString("\"%s\"", (fileSystem->GetProgramDir() + "Resources/").CString()));        
        vargs.Insert(0, "--resourcePrefix");
    }

    if (debug)
        vargs.Insert(0, "--debug");

    if (addArgs.Length() > 0)
        vargs.Insert(0, addArgs.Split(' '));

    String dump;
    dump.Join(vargs, " ");
    ATOMIC_LOGINFOF("Launching Broker %s %s", playerBinary.CString(), dump.CString());

    IPC* ipc = GetSubsystem<IPC>();
    playerBroker_ = ipc->SpawnWorker(playerBinary, vargs);

    if (playerBroker_)
    {
        SubscribeToEvent(playerBroker_, E_IPCWORKERSTART, ATOMIC_HANDLER(EditorMode, HandleIPCWorkerStarted));

        SubscribeToEvent(E_IPCPLAYERPAUSERESUMEREQUEST, ATOMIC_HANDLER(EditorMode, HandleIPCPlayerPauseResumeRequest));
        SubscribeToEvent(E_IPCPLAYERUPDATESPAUSEDRESUMED, ATOMIC_HANDLER(EditorMode, HandleIPCPlayerUpdatesPausedResumed));
        SubscribeToEvent(E_IPCPLAYERPAUSESTEPREQUEST, ATOMIC_HANDLER(EditorMode, HandleIPCPlayerPauseStepRequest));
        SubscribeToEvent(E_IPCPLAYEREXITREQUEST, ATOMIC_HANDLER(EditorMode, HandleIPCPlayerExitRequest));
    

        SubscribeToEvent(playerBroker_, E_IPCJSERROR, ATOMIC_HANDLER(EditorMode, HandleIPCJSError));
        SubscribeToEvent(playerBroker_, E_IPCWORKEREXIT, ATOMIC_HANDLER(EditorMode, HandleIPCWorkerExit));
        SubscribeToEvent(playerBroker_, E_IPCWORKERLOG, ATOMIC_HANDLER(EditorMode, HandleIPCWorkerLog));
    }

    return playerBroker_.NotNull();

}
void AtomicTool::Start()
{
    // Subscribe to events
    SubscribeToEvent(E_COMMANDERROR, HANDLER(AtomicTool, HandleCommandError));
    SubscribeToEvent(E_COMMANDFINISHED, HANDLER(AtomicTool, HandleCommandFinished));

    SubscribeToEvent(E_LICENSE_EULAREQUIRED, HANDLER(AtomicTool, HandleLicenseEulaRequired));
    SubscribeToEvent(E_LICENSE_ACTIVATIONREQUIRED, HANDLER(AtomicTool, HandleLicenseActivationRequired));
    SubscribeToEvent(E_LICENSE_ERROR, HANDLER(AtomicTool, HandleLicenseError));
    SubscribeToEvent(E_LICENSE_SUCCESS, HANDLER(AtomicTool, HandleLicenseSuccess));

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

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

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

//#ifdef ATOMIC_DEV_BUILD

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

    if (!cliDataPath_.Length())
    {
        cliDataPath_ = env->GetRootSourceDir() + "/Resources/";
    }

//#endif

    tsystem->SetCLI();
    tsystem->SetDataPath(cliDataPath_);


    if (activationKey_.Length())
    {
        DoActivation();
        return;
    } else if (deactivate_)
    {
        DoDeactivation();
        return;
    }

    BuildSystem* buildSystem = GetSubsystem<BuildSystem>();

    SharedPtr<CommandParser> parser(new CommandParser(context_));

    SharedPtr<Command> cmd(parser->Parse(arguments));
    if (!cmd)
    {
        String error = "No command found";

        if (parser->GetErrorMessage().Length())
            error = parser->GetErrorMessage();

        ErrorExit(error);
        return;
    }

    if (cmd->RequiresProjectLoad())
    {
        FileSystem* fileSystem = GetSubsystem<FileSystem>();

        String projectDirectory = fileSystem->GetCurrentDir();

        Vector<String> projectFiles;
        fileSystem->ScanDir(projectFiles, projectDirectory, "*.atomic", SCAN_FILES, false);
        if (!projectFiles.Size())
        {
            ErrorExit(ToString("No .atomic project file in %s", projectDirectory.CString()));
            return;
        }
        else if (projectFiles.Size() > 1)
        {
            ErrorExit(ToString("Multiple .atomic project files found in %s", projectDirectory.CString()));
            return;
        }

        String projectFile = projectDirectory + "/" + projectFiles[0];

        if (!tsystem->LoadProject(projectFile))
        {
            //ErrorExit(ToString("Failed to load project: %s", projectFile.CString()));
            //return;
        }

        // Set the build path
        String buildFolder = projectDirectory + "/" + "Build";
        buildSystem->SetBuildPath(buildFolder);

        if (!fileSystem->DirExists(buildFolder))
        {
            fileSystem->CreateDir(buildFolder);

            if (!fileSystem->DirExists(buildFolder))
            {
                ErrorExit(ToString("Failed to create build folder: %s", buildFolder.CString()));
                return;
            }
        }

    }

    command_ = cmd;

    // BEGIN LICENSE MANAGEMENT
    if (cmd->RequiresLicenseValidation())
    {
        GetSubsystem<LicenseSystem>()->Initialize();
    }
    else
    {
        if (command_.Null())
        {
            GetSubsystem<Engine>()->Exit();
            return;
        }

        command_->Run();
    }
    // END LICENSE MANAGEMENT

}