浏览代码

Adding project cache clean/generate command, some refactoring to command system

Josh Engebretson 8 年之前
父节点
当前提交
1fa2531b6f

+ 5 - 33
Source/AtomicTool/AtomicTool.cpp

@@ -223,47 +223,19 @@ void AtomicTool::Start()
 
     if (cmd->RequiresProjectLoad())
     {
-        FileSystem* fileSystem = GetSubsystem<FileSystem>();
-
-        String projectPath = cmd->GetProjectPath();
-            
-        // default to current directly if command doesn't provide the path
-        if (!projectPath.Length())
-            projectPath = fileSystem->GetCurrentDir();
-
-        String projectFile;
-        if (projectPath.EndsWith(".atomic", false))
+        if (!cmd->LoadProject())
         {
-            projectFile = projectPath;
-            projectPath = GetPath(projectPath);
-        }
-        else
-        {
-            Vector<String> projectFiles;
-            fileSystem->ScanDir(projectFiles, projectPath, "*.atomic", SCAN_FILES, false);
-            if (!projectFiles.Size())
-            {
-                ErrorExit(ToString("No .atomic project file in %s", projectPath.CString()));
-                return;
-            }
-            else if (projectFiles.Size() > 1)
-            {
-                ErrorExit(ToString("Multiple .atomic project files found in %s", projectPath.CString()));
-                return;
-            }
-            projectFile = projectPath + "/" + projectFiles[0];
+            ErrorExit(ToString("Failed to load project: %s", cmd->GetProjectPath().CString()));
+            return;
         }
 
-        if (!tsystem->LoadProject(projectFile))
-        {
-            //ErrorExit(ToString("Failed to load project: %s", projectFile.CString()));
-            //return;
-        }
+        String projectPath = cmd->GetProjectPath();
 
         // Set the build path
         String buildFolder = projectPath + "/" + "Build";
         buildSystem->SetBuildPath(buildFolder);
 
+        FileSystem* fileSystem = GetSubsystem<FileSystem>();
         if (!fileSystem->DirExists(buildFolder))
         {
             fileSystem->CreateDir(buildFolder);

+ 1 - 1
Source/ToolCore/Command/BindCmd.cpp

@@ -45,7 +45,7 @@ BindCmd::~BindCmd()
 
 }
 
-bool BindCmd::Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
+bool BindCmd::ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
 {
     String argument = arguments[startIndex].ToLower();
     sourceRootFolder_ = startIndex + 1 < arguments.Size() ? arguments[startIndex + 1] : String::EMPTY;

+ 4 - 2
Source/ToolCore/Command/BindCmd.h

@@ -38,12 +38,14 @@ public:
     BindCmd(Context* context);
     virtual ~BindCmd();
 
-    bool Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
-
     void Run();
 
     bool RequiresProjectLoad() { return false; }
 
+protected:
+
+    bool ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
+
 private:
 
     String sourceRootFolder_;

+ 1 - 1
Source/ToolCore/Command/BuildCmd.cpp

@@ -46,7 +46,7 @@ BuildCmd::~BuildCmd()
 
 }
 
-bool BuildCmd::Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
+bool BuildCmd::ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
 {
     String argument = arguments[startIndex].ToLower();
     String value = startIndex + 1 < arguments.Size() ? arguments[startIndex + 1] : String::EMPTY;

+ 4 - 2
Source/ToolCore/Command/BuildCmd.h

@@ -38,10 +38,12 @@ public:
     BuildCmd(Context* context);
     virtual ~BuildCmd();
 
-    bool Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
-
     void Run();
 
+protected:
+
+    bool ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
+
 private:
 
     void HandleBuildComplete(StringHash eventType, VariantMap& eventData);

+ 177 - 0
Source/ToolCore/Command/CacheCmd.cpp

@@ -0,0 +1,177 @@
+//
+// Copyright (c) 2014-2017 THUNDERBEAST GAMES LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include <Atomic/Core/StringUtils.h>
+#include <Atomic/IO/Log.h>
+#include <Atomic/IO/File.h>
+
+#include "../Assets/AssetDatabase.h"
+#include "../ToolSystem.h"
+#include "../ToolEnvironment.h"
+#include "../Project/Project.h"
+#include "../Build/BuildEvents.h"
+#include "../Build/BuildSystem.h"
+
+#include "CacheCmd.h"
+
+namespace ToolCore
+{
+
+CacheCmd::CacheCmd(Context* context) : Command(context),
+    cleanCache_(false),
+    generateCache_(false)
+{
+
+}
+
+CacheCmd::~CacheCmd()
+{
+
+}
+
+bool CacheCmd::ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
+{
+    for (unsigned i = startIndex; i < arguments.Size(); i++)
+    {
+        if (arguments[i].Length() > 1)
+        {
+            String argument = arguments[i].ToLower();
+
+            if (argument == "generate")
+            {
+                generateCache_ = true;
+                continue;
+            }
+
+            // process any argument/value pairs
+            if (arguments[i][0] != '-')
+                continue;
+
+            // eat additonal argument '-'
+            while (argument.StartsWith("-"))
+            {
+                argument.Erase(0);
+            }
+
+            String value = i + 1 < arguments.Size() ? arguments[i + 1] : String::EMPTY;
+
+            if (argument == "clean")
+                cleanCache_ = true;
+
+        }
+    }
+
+    return true;
+}
+
+
+bool CacheCmd::CreateCacheDirectory() const
+{
+    FileSystem* fileSystem = GetSubsystem<FileSystem>();
+
+    if (fileSystem->DirExists(cachePath_))
+        return true;
+
+    fileSystem->CreateDir(cachePath_);
+
+    if (!fileSystem->DirExists(cachePath_))
+    {
+        ATOMIC_LOGERRORF("Unable to create cache directory %s", cachePath_.CString());
+        return false;
+    }
+
+    return true;
+}
+
+bool CacheCmd::RemoveCacheDirectory() const
+{
+    FileSystem* fileSystem = GetSubsystem<FileSystem>();
+
+    if (!fileSystem->DirExists(cachePath_))
+        return true;
+
+    fileSystem->RemoveDir(cachePath_, true);
+
+    if (fileSystem->DirExists(cachePath_))
+    {
+        ATOMIC_LOGERRORF("Unable to remove cache directory %s", cachePath_.CString());
+        return false;
+    }
+
+    return true;
+}
+
+bool CacheCmd::CleanCache() const
+{
+    ATOMIC_LOGINFO("Cleaning Cache...");
+
+    if (!RemoveCacheDirectory())
+        return false;
+
+    if (!CreateCacheDirectory())
+        return false;
+
+   return true;
+}
+
+bool CacheCmd::GenerateCache() const
+{
+    ATOMIC_LOGINFO("Generating Cache... hold on");
+
+    AssetDatabase* database = GetSubsystem<AssetDatabase>();
+    database->ReimportAllAssets();
+
+    ATOMIC_LOGINFO("Cache Generated");
+
+    return true;
+}
+
+void CacheCmd::Run()
+{
+    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
+    ToolEnvironment* env = GetSubsystem<ToolCore::ToolEnvironment>();
+    Project* project = tsystem->GetProject();
+
+    cachePath_ = AddTrailingSlash(project->GetProjectPath()) + "Cache";
+
+    if (cleanCache_)
+    {
+        if (!CleanCache())
+        {
+            Error("Unable to clean cache");
+            return;
+        }
+    }
+
+    if (generateCache_)
+    {
+        if (!GenerateCache())
+        {
+            Error("Unable to generate cache");
+            return;
+        }
+    }
+
+    Finished();
+}
+
+}

+ 70 - 0
Source/ToolCore/Command/CacheCmd.h

@@ -0,0 +1,70 @@
+//
+// Copyright (c) 2014-2017 THUNDERBEAST GAMES LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "Command.h"
+
+using namespace Atomic;
+
+namespace ToolCore
+{
+
+
+/// Command for cleaning and regenerating a Project resource cache
+class CacheCmd: public Command
+{
+
+    /// Example usage:
+    /// AtomicTool cache --clean --project C:\Path\To\MyProject (cleans cache folder)
+    /// AtomicTool cache generate --project C:\Path\To\MyProject (regenerates the project cache)
+    /// AtomicTool cache generate --clean --project C:\Path\To\MyProject (cleans and then regenerates the project cache)
+
+    ATOMIC_OBJECT(CacheCmd, Command)
+
+public:
+
+    CacheCmd(Context* context);
+    virtual ~CacheCmd();
+
+    void Run();
+
+protected:
+
+    bool ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
+
+private:
+
+    bool CreateCacheDirectory() const;
+    bool RemoveCacheDirectory() const;
+
+    bool CleanCache() const;
+
+    bool GenerateCache() const;
+
+    bool cleanCache_;
+    bool generateCache_;
+    String cachePath_;
+
+};
+
+}

+ 82 - 4
Source/ToolCore/Command/Command.cpp

@@ -20,6 +20,8 @@
 // THE SOFTWARE.
 //
 
+#include <Atomic/IO/Log.h>
+
 #include "../ToolSystem.h"
 #include "../Project/Project.h"
 
@@ -39,12 +41,88 @@ Command::~Command()
 
 }
 
-bool Command::Parse(const String& command)
+bool Command::LoadProject()
+{
+    if (!projectPath_.Length())
+        return false;
+
+    FileSystem* fileSystem = GetSubsystem<FileSystem>();
+
+    // default to current directly if command doesn't provide the path
+    if (!projectPath_.Length())
+        projectPath_ = fileSystem->GetCurrentDir();
+
+    String projectFile;
+    if (projectPath_.EndsWith(".atomic", false))
+    {
+        projectFile = projectPath_;
+        projectPath_ = GetPath(projectPath_);
+    }
+    else
+    {
+        Vector<String> projectFiles;
+        fileSystem->ScanDir(projectFiles, projectPath_, "*.atomic", SCAN_FILES, false);
+        if (!projectFiles.Size())
+        {
+            ATOMIC_LOGERRORF("No .atomic project file in %s", projectPath_.CString());
+            return false;
+        }
+        else if (projectFiles.Size() > 1)
+        {
+            ATOMIC_LOGERRORF("Multiple .atomic project files found in %s", projectPath_.CString());
+            return false;
+        }
+        projectFile = projectPath_ + "/" + projectFiles[0];
+    }
+
+    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
+
+    if (!tsystem->LoadProject(projectFile))
+    {
+        ATOMIC_LOGERRORF("Failed to load project: %s", projectFile.CString());
+        return false;
+    }
+
+    return true;
+
+}
+
+void Command::ParseCommonArguments(const Vector<String> &arguments, String &errorMsg)
+{
+    for (unsigned i = 0; i < arguments.Size(); ++i)
+    {
+        if (arguments[i].Length() > 1 && arguments[i][0] == '-')
+        {
+            String argument = arguments[i].Substring(1).ToLower();
+            String value = i + 1 < arguments.Size() ? arguments[i + 1] : String::EMPTY;
+
+            // eat additonal argument '-'
+            while (argument.StartsWith("-"))
+            {
+                argument.Erase(0);
+            }
+
+            if (argument == "project" && value.Length())
+            {
+                projectPath_ = value;
+            }
+        }
+    }
+
+}
+
+bool Command::Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
 {
-    Vector<String> args = command.Split(' ');
-    String errorMsg;
+    errorMsg = String::EMPTY;
+
+    ParseCommonArguments(arguments, errorMsg);
+
+    if (errorMsg.Length())
+    {
+        return false;
+    }
 
-    return Parse(args, 0, errorMsg);
+    return ParseInternal(arguments, startIndex, errorMsg);
 }
 
 void Command::Error(const String& errorMsg)

+ 12 - 6
Source/ToolCore/Command/Command.h

@@ -49,9 +49,7 @@ public:
     Command(Context* context);
     virtual ~Command();
 
-    bool Parse(const String& command);
-
-    virtual bool Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg) = 0;
+    bool Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
 
     virtual void Run() = 0;
 
@@ -63,13 +61,21 @@ public:
 
     virtual bool RequiresProjectLoad() { return true; }
 
-    virtual const String& GetProjectPath() const { return String::EMPTY; }
+    bool LoadProject();
+
+    virtual const String& GetProjectPath() const { return projectPath_; }
 
     virtual bool RequiresLicenseValidation() { return false; }
 
-private:
+protected:
+
+    virtual bool ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg) = 0;
+
+    void ParseCommonArguments(const Vector<String>& arguments, String &errorMsg);
+
+    float timeOut_;    
 
-    float timeOut_;
+    String projectPath_;
 
 };
 

+ 5 - 0
Source/ToolCore/Command/CommandParser.cpp

@@ -30,6 +30,7 @@
 #include "BindCmd.h"
 #include "NETCmd.h"
 #include "ProjectCmd.h"
+#include "CacheCmd.h"
 
 namespace ToolCore
 {
@@ -86,6 +87,10 @@ Command* CommandParser::Parse(const Vector<String>& arguments)
             {
                 cmd = new ProjectCmd(context_);
             }
+            else if (argument == "cache")
+            {
+                cmd = new CacheCmd(context_);
+            }
 
         }
 

+ 1 - 1
Source/ToolCore/Command/EditCmd.cpp

@@ -47,7 +47,7 @@ EditCmd::~EditCmd()
 
 }
 
-bool EditCmd::Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
+bool EditCmd::ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
 {
     String argument = arguments[startIndex].ToLower();
     String value = startIndex + 1 < arguments.Size() ? arguments[startIndex + 1] : String::EMPTY;

+ 5 - 3
Source/ToolCore/Command/EditCmd.h

@@ -36,12 +36,14 @@ class EditCmd: public Command
 public:
 
     EditCmd(Context* context);
-    virtual ~EditCmd();
-
-    bool Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
+    virtual ~EditCmd();    
 
     void Run();
 
+protected:
+
+    bool ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
+
 private:
 
     bool LaunchEditorProcess(const String& command, const Vector<String>& args, const String& initialDirectory);

+ 1 - 1
Source/ToolCore/Command/ImportCmd.cpp

@@ -48,7 +48,7 @@ ImportCmd::~ImportCmd()
 
 }
 
-bool ImportCmd::Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
+bool ImportCmd::ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
 {
     String argument = arguments[startIndex].ToLower();
     String value = startIndex + 1 < arguments.Size() ? arguments[startIndex + 1] : String::EMPTY;

+ 4 - 1
Source/ToolCore/Command/ImportCmd.h

@@ -38,11 +38,14 @@ public:
     ImportCmd(Context* context);
     virtual ~ImportCmd();
 
-    bool Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
     void Run();
 
     bool RequiresProjectLoad() { return true; }
 
+protected:
+
+    bool ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
+
 private:
 
     String assetFilename_;

+ 1 - 1
Source/ToolCore/Command/NETCmd.cpp

@@ -56,7 +56,7 @@ NETCmd::~NETCmd()
 
 }
 
-bool NETCmd::Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
+bool NETCmd::ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
 {
     String argument = arguments[startIndex].ToLower();
     command_ = startIndex + 1 < arguments.Size() ? arguments[startIndex + 1].ToLower() : String::EMPTY;

+ 4 - 5
Source/ToolCore/Command/NETCmd.h

@@ -42,23 +42,22 @@ public:
     NETCmd(Context* context);
     virtual ~NETCmd();
 
-    bool Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
-
     void Run();
 
     bool RequiresProjectLoad() { return requiresProjectLoad_; }
 
     const String& GetProjectPath() const { return projectPath_; }
 
+protected:
+
+    bool ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
+
 private:
 
     void HandleNETBuildResult(StringHash eventType, VariantMap& eventData);
 
     String command_;
 
-    // genresources command
-    String projectPath_;
-
     // parse command
     String assemblyPath_;
 

+ 1 - 1
Source/ToolCore/Command/NewProjectCmd.cpp

@@ -44,7 +44,7 @@ NewProjectCmd::~NewProjectCmd()
 
 }
 
-bool NewProjectCmd::Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
+bool NewProjectCmd::ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
 {
     String argument = arguments[startIndex].ToLower();
     String value = startIndex + 1 < arguments.Size() ? arguments[startIndex + 1] : String::EMPTY;

+ 4 - 2
Source/ToolCore/Command/NewProjectCmd.h

@@ -38,12 +38,14 @@ public:
     NewProjectCmd(Context* context);
     virtual ~NewProjectCmd();
 
-    bool Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
-
     void Run();
 
     bool RequiresProjectLoad() { return false; }
 
+protected:
+
+    bool ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
+
 private:
 
     String projectPath_;

+ 1 - 1
Source/ToolCore/Command/PlayCmd.cpp

@@ -47,7 +47,7 @@ PlayCmd::~PlayCmd()
 
 }
 
-bool PlayCmd::Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
+bool PlayCmd::ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
 {
     String argument = arguments[startIndex].ToLower();
     String value = startIndex + 1 < arguments.Size() ? arguments[startIndex + 1] : String::EMPTY;

+ 5 - 3
Source/ToolCore/Command/PlayCmd.h

@@ -36,12 +36,14 @@ class PlayCmd: public Command
 public:
 
     PlayCmd(Context* context);
-    virtual ~PlayCmd();
-
-    bool Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
+    virtual ~PlayCmd();    
 
     void Run();
 
+protected:
+
+    bool ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
+
 private:
 
     bool LaunchPlayerProcess(const String& command, const Vector<String>& args, const String& initialDirectory);

+ 1 - 1
Source/ToolCore/Command/ProjectCmd.cpp

@@ -52,7 +52,7 @@ ProjectCmd::~ProjectCmd()
 }
 
 // usage: project <projectPath> [cache (-clean)]
-bool ProjectCmd::Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
+bool ProjectCmd::ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg)
 {
     String argument = arguments[startIndex].ToLower();
     if (argument != "project")

+ 5 - 6
Source/ToolCore/Command/ProjectCmd.h

@@ -31,27 +31,26 @@ namespace ToolCore
 
 class ProjectCmd: public Command
 {
-    ATOMIC_OBJECT(ProjectCmd, Command);
+    ATOMIC_OBJECT(ProjectCmd, Command)
 
 public:
 
     ProjectCmd(Context* context);
     virtual ~ProjectCmd();
 
-    bool Parse(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
-
     void Run();
 
-    bool RequiresProjectLoad() { return requiresProjectLoad_; }
+    bool RequiresProjectLoad() { return requiresProjectLoad_; }    
+
+protected:
 
-    const String& GetProjectPath() const { return projectPath_; }
+    bool ParseInternal(const Vector<String>& arguments, unsigned startIndex, String& errorMsg);
 
 private:
 
     void HandleProjectBeginLoad(StringHash eventType, VariantMap& eventData);
     void HandleProjectLoaded(StringHash eventType, VariantMap& eventData);
 
-    String projectPath_;
     String command_;
     bool requiresProjectLoad_;
     int options_;