Explorar o código

Merge pull request #936 from AtomicGameEngine/JME-ATOMIC-NETSTANDALONE

Standalone Atomic Editor can handle C# projects with VS2015 installed
JoshEngebretson %!s(int64=9) %!d(string=hai) anos
pai
achega
5eb2b21f80

+ 8 - 0
Build/Scripts/BuildWindows.js

@@ -56,6 +56,14 @@ namespace('build', function() {
       fs.copySync(buildDir +  "Source/AtomicPlayer/Application/Release/D3DCompiler_47.dll",
         editorAppFolder + "Resources/ToolData/Deployment/Windows/x64/D3DCompiler_47.dll");
 
+      // AtomicNET
+
+      fs.copySync(atomicRoot + "Artifacts/AtomicNET/Release",
+        editorAppFolder + "Resources/ToolData/AtomicNET/Release");
+
+      fs.copySync(buildDir +  "Source/AtomicPlayer/Application/Release/D3DCompiler_47.dll",
+        editorAppFolder + "Resources/ToolData/AtomicNET/Release/D3DCompiler_47.dll");
+
       console.log("Atomic Editor build to ", editorAppFolder);
 
       complete();

+ 2 - 1
Build/Scripts/Windows/CompileAtomicEditor.bat

@@ -1,3 +1,4 @@
 call "%VS140COMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat"
 cmake ..\\..\\..\\ -DATOMIC_DEV_BUILD=0 -G "Visual Studio 14 2015 Win64"
-msbuild /m Atomic.sln /t:AtomicEditor /t:AtomicPlayer /p:Configuration=Release /p:Platform=x64
+msbuild /m Atomic.sln /t:AtomicEditor /t:AtomicPlayer /t:AtomicNETNative /p:Configuration=Release /p:Platform=x64
+msbuild Source/AtomicTool/GenerateAtomicNET.vcxproj /p:Configuration=Release /p:Platform=x64

+ 35 - 2
Script/AtomicEditor/hostExtensions/languageExtensions/CSharpLanguageExtension.ts

@@ -64,6 +64,7 @@ export default class CSharpLanguageExtension implements Editor.HostExtensions.Re
             const menu = this.serviceRegistry.uiServices.createPluginMenuItemSource("AtomicNET", {});
             menu.addItem(new Atomic.UIMenuItem("Open Solution", `${this.name}.opensolution`));
             menu.addItem(new Atomic.UIMenuItem("Compile Project", `${this.name}.compileproject`));
+            menu.addItem(new Atomic.UIMenuItem("Generate Solution", `${this.name}.generatesolution`));
             this.menuCreated = true;
         }
 
@@ -174,8 +175,15 @@ export default class CSharpLanguageExtension implements Editor.HostExtensions.Re
         if (extension == this.name) {
             switch (action) {
                 case "compileproject":
-                this.doFullCompile();
-                return true;
+                    this.doFullCompile();
+                    return true;
+                case "opensolution":
+                    this.openSolution();
+                    return true;
+                case "generatesolution":
+                    this.generateSolution();
+                    return true;
+
             }
         }
     }
@@ -185,6 +193,31 @@ export default class CSharpLanguageExtension implements Editor.HostExtensions.Re
     */
     doFullCompile() {
 
+        if (ToolCore.netProjectSystem)
+            ToolCore.netProjectSystem.buildAtomicProject();
+
+    }
+    /**
+    * Open Solution
+    */
+    openSolution() {
+
+        if (ToolCore.netProjectSystem) {
+            ToolCore.netProjectSystem.openSolution();
+        }
+
     }
 
+    /**
+    * Generate Solution
+    */
+    generateSolution() {
+
+        if (ToolCore.netProjectSystem) {
+            ToolCore.netProjectSystem.generateSolution();
+        }
+
+    }
+
+
 }

+ 13 - 3
Source/AtomicApp/Player/IPCPlayerApp.cpp

@@ -75,6 +75,9 @@ namespace Atomic
             ErrorExit("IPCPlayerApp::ProcessArguments FileSystem subsystem does not exist");
         }
 
+        String resourcePrefix;
+        engineParameters_["ResourcePrefixPath"] = "";
+
         for (unsigned i = 0; i < arguments_.Size(); ++i)
         {
             if (arguments_[i].Length() > 1)
@@ -90,10 +93,13 @@ namespace Atomic
                 {
                     debugPlayer_ = true;
                 }
+                else if (argument == "--resourceprefix" && value.Length())
+                {
+                    resourcePrefix = value;
+                    engineParameters_["ResourcePrefixPath"] = resourcePrefix;
+                }
                 else if (argument == "--project" && value.Length())
                 {
-                    engineParameters_["ResourcePrefixPath"] = "";
-
                     value = AddTrailingSlash(value);
 
                     AddEngineConfigSearchPath(value + "Settings/");
@@ -115,7 +121,11 @@ namespace Atomic
 #ifdef __APPLE__
                     engineParameters_["ResourcePrefixPath"] = "../Resources";
 #else
-                    engineParameters_["ResourcePrefixPath"] = fileSystem->GetProgramDir() + "Resources";
+                    if (!resourcePrefix.Length())
+                    {
+                        engineParameters_["ResourcePrefixPath"] = fileSystem->GetProgramDir() + "Resources";
+                    }
+
 #endif
 
                     String resourcePaths = ToString("CoreData;PlayerData;%s/;%s/Resources;%s;%sCache",

+ 6 - 0
Source/AtomicEditor/EditorMode/AEEditorMode.cpp

@@ -165,6 +165,12 @@ bool EditorMode::PlayProject(String addArgs, bool debug)
 
     vargs = args.Split(' ');
 
+    if (managed)
+    {            
+        vargs.Insert(0, ToString("\"%s\"", (fileSystem->GetProgramDir() + "Resources/").CString()));        
+        vargs.Insert(0, "--resourcePrefix");
+    }
+
     if (debug)
         vargs.Insert(0, "--debug");
 

+ 21 - 12
Source/ToolCore/NETTools/NETBuildSystem.cpp

@@ -244,7 +244,7 @@ namespace ToolCore
             ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
             const String& nugetBinary = tenv->GetAtomicNETNuGetBinary();
 
-            if (!fileSystem->FileExists(nugetBinary))
+            if (requiresNuGet && !fileSystem->FileExists(nugetBinary))
             {
                 CurrentBuildError(ToString("NuGet binary is missing (%s)", nugetBinary.CString()));
                 return;
@@ -327,18 +327,8 @@ namespace ToolCore
 
     }
 
-    void NETBuildSystem::HandleBuildAtomicProject(StringHash eventType, VariantMap& eventData)
+    NETBuild* NETBuildSystem::BuildAtomicProject(Project* project)
     {
-        using namespace NETBuildAtomicProject;
-
-        Project* project = static_cast<Project*>(eventData[P_PROJECT].GetPtr());
-
-        if (!project)
-        {
-            LOGERROR("NETBuildSystem::HandleBuildAtomicProject - null project");
-            return;
-        }
-
         String platform;
         String configuration;
 
@@ -367,6 +357,25 @@ namespace ToolCore
 
         LOGINFOF("Received build for project %s", project->GetProjectFilePath().CString());
 
+        return build;
+
+    }
+
+
+    void NETBuildSystem::HandleBuildAtomicProject(StringHash eventType, VariantMap& eventData)
+    {
+        using namespace NETBuildAtomicProject;
+
+        Project* project = static_cast<Project*>(eventData[P_PROJECT].GetPtr());
+
+        if (!project)
+        {
+            LOGERROR("NETBuildSystem::HandleBuildAtomicProject - null project");
+            return;
+        }
+
+        BuildAtomicProject(project);
+
     }
 
     NETBuild* NETBuildSystem::Build(const String& solutionPath, const String& platform, const String& configuration)

+ 2 - 0
Source/ToolCore/NETTools/NETBuildSystem.h

@@ -87,6 +87,8 @@ namespace ToolCore
         /// Build either a .sln or .json configuration file
         NETBuild* Build(const String& solutionPath, const String& platform, const String& configuration = "Release");
 
+        NETBuild* BuildAtomicProject(Project* project);
+
     private:
 
         void CurrentBuildError(String errorText);

+ 14 - 1
Source/ToolCore/NETTools/NETProjectGen.cpp

@@ -439,10 +439,23 @@ namespace ToolCore
                     XMLElement propertyGroup = project.CreateChild("PropertyGroup");
                     propertyGroup.SetAttribute("Condition", ToString("'$(Configuration)|$(Platform)' == '%s|AnyCPU'", cfg.CString()));
 
+                    String startArguments;
+
+#ifdef ATOMIC_DEV_BUILD
                     String playerBin = tenv->GetAtomicNETRootDir() + cfg + "/AtomicPlayer.exe";
+#else
+                    String playerBin = tenv->GetAtomicNETRootDir() + "Release/AtomicPlayer.exe";
+
+                    startArguments += ToString("--resourcePrefix \"%s\" ", (fileSystem->GetProgramDir() + "Resources/").CString());
+
+#endif
+
                     propertyGroup.CreateChild("StartAction").SetValue("Program");                    
                     propertyGroup.CreateChild("StartProgram").SetValue(playerBin );
-                    propertyGroup.CreateChild("StartArguments").SetValue(ToString("--project %s", atomicProject->GetProjectPath().CString()));
+
+                    startArguments += ToString("--project \"%s\"", atomicProject->GetProjectPath().CString());
+
+                    propertyGroup.CreateChild("StartArguments").SetValue(startArguments);
                     
                 }
 

+ 107 - 29
Source/ToolCore/NETTools/NETProjectSystem.cpp

@@ -62,6 +62,23 @@ namespace ToolCore
         projectAssemblyDirty_ = false;
     }
 
+    void NETProjectSystem::OpenSolution()
+    {
+        if (!visualStudioPath_.Length())
+            return;
+
+        FileSystem* fileSystem = GetSubsystem<FileSystem>();
+
+        if (!fileSystem->FileExists(solutionPath_))
+        {
+            if (!GenerateSolution())
+                return;
+        }
+
+        OpenSourceFile(String::EMPTY);
+
+    }
+
     void NETProjectSystem::OpenSourceFile(const String& sourceFilePath)
     {
         if (!visualStudioPath_.Length())
@@ -75,7 +92,9 @@ namespace ToolCore
             vsSubprocess_ = 0;
 
             args.Push(solutionPath_);
-            args.Push(sourceFilePath);
+
+            if (sourceFilePath.Length())
+                args.Push(sourceFilePath);
 
             try
             {
@@ -89,6 +108,9 @@ namespace ToolCore
         }
         else
         {
+            if (!sourceFilePath.Length())
+                return;
+
             try
             {
                 std::vector<std::string> args;
@@ -105,56 +127,112 @@ namespace ToolCore
 
     }
 
-    void NETProjectSystem::HandleUpdate(StringHash eventType, VariantMap& eventData)
+    void NETProjectSystem::HandleNETBuildResult(StringHash eventType, VariantMap& eventData)
     {
-        using namespace Update;
+        using namespace NETBuildResult;
 
-        float delta = eventData[P_TIMESTEP].GetFloat();
+        if (eventData[P_SUCCESS].GetBool())
+        {
+            LOGINFOF("NETBuild Success for project");
+        }
+        else
+        {
+            const String& errorText = eventData[P_ERRORTEXT].GetString();
 
-        quietPeriod_ -= delta;
+            LOGERRORF("\n%s\n", errorText.CString());
+            LOGERRORF("NETBuild Error for project");
+        }
 
-        if (quietPeriod_ < 0.0f)
-            quietPeriod_ = 0.0f;
+    }
 
-        if (quietPeriod_ > 0.0f)
-            return;
+    void NETProjectSystem::BuildAtomicProject()
+    {
+        FileSystem* fileSystem = GetSubsystem<FileSystem>();
 
-        if (solutionDirty_)
+        if (!fileSystem->FileExists(solutionPath_))
         {
-            ToolSystem* tsystem = GetSubsystem<ToolSystem>();
-            Project* project = tsystem->GetProject();
-
-            SharedPtr<NETProjectGen> gen(new NETProjectGen(context_));
-
-            gen->SetScriptPlatform("WINDOWS");
-
-            if (!gen->LoadProject(project))
+            if (!GenerateSolution())
             {
+                LOGERRORF("NETProjectSystem::BuildAtomicProject - solutionPath does not exist: %s", solutionPath_.CString());
                 return;
             }
+        }
+
+#ifdef ATOMIC_PLATFORM_WINDOWS
+
+        Project* project = GetSubsystem<ToolSystem>()->GetProject();
+        NETBuildSystem* buildSystem = GetSubsystem<NETBuildSystem>();
 
-            if (!gen->Generate())
+        if (buildSystem)
+        {
+            NETBuild* build = buildSystem->BuildAtomicProject(project);
+
+            if (build)
             {
-                return;
+                build->SubscribeToEvent(E_NETBUILDRESULT, HANDLER(NETProjectSystem, HandleNETBuildResult));
             }
 
-            solutionDirty_ = false;
+        }
+#endif
 
+    }
+
+    bool NETProjectSystem::GenerateSolution()
+    {
+        ToolSystem* tsystem = GetSubsystem<ToolSystem>();
+        Project* project = tsystem->GetProject();
+
+        if (!project)
+        {
+            LOGERRORF("NETProjectSystem::GenerateSolution - No Project Loaded");
+            return false;
         }
 
-        if (projectAssemblyDirty_)
+        SharedPtr<NETProjectGen> gen(new NETProjectGen(context_));
+
+        gen->SetScriptPlatform("WINDOWS");
+
+        if (!gen->LoadProject(project))
+        {
+            LOGERRORF("NETProjectSystem::GenerateSolution - Unable to Load Project");
+            return false;
+        }
+
+        if (!gen->Generate())
         {
-            using namespace NETBuildAtomicProject;
+            LOGERRORF("NETProjectSystem::GenerateSolution - Unable to Generate Project");
+            return false;
+        }
 
-            VariantMap eventData;
-            Project* project = GetSubsystem<ToolSystem>()->GetProject();
-            eventData[P_PROJECT] = project;
+        return true;
 
-            // We need to rebuild the project assembly
-            SendEvent(E_NETBUILDATOMICPROJECT, eventData);
+    }
 
-            projectAssemblyDirty_ = false;
 
+    void NETProjectSystem::HandleUpdate(StringHash eventType, VariantMap& eventData)
+    {
+        using namespace Update;
+
+        float delta = eventData[P_TIMESTEP].GetFloat();
+
+        quietPeriod_ -= delta;
+
+        if (quietPeriod_ < 0.0f)
+            quietPeriod_ = 0.0f;
+
+        if (quietPeriod_ > 0.0f)
+            return;
+
+        if (solutionDirty_)
+        {
+            solutionDirty_ = false;
+            GenerateSolution();
+        }
+
+        if (projectAssemblyDirty_)
+        {        
+            BuildAtomicProject();
+            projectAssemblyDirty_ = false;
         }
 
     }

+ 11 - 1
Source/ToolCore/NETTools/NETProjectSystem.h

@@ -50,16 +50,26 @@ namespace ToolCore
         NETProjectSystem(Context* context);
         virtual ~NETProjectSystem();
 
+        bool GetVisualStudioAvailable() const { return visualStudioPath_.Length() != 0; }
+
         const String& GetSolutionPath() const { return solutionPath_; }
 
-        bool GetVisualStudioAvailable() const { return visualStudioPath_.Length() != 0; }
+        void BuildAtomicProject();        
+
+        /// Open the solution, if opening a source file, better to call OpenSourceFile as will launch VS instance with source file loaded
+        /// otherwise, no guarantee where source file will load when multiple VS instances running
+        void OpenSolution();       
 
         void OpenSourceFile(const String& sourceFilePath);
 
+        bool GenerateSolution();
+
     private:
 
         void HandleUpdate(StringHash eventType, VariantMap& eventData);
 
+        void HandleNETBuildResult(StringHash eventType, VariantMap& eventData);
+
         void HandleFileChanged(StringHash eventType, VariantMap& eventData);
         void HandleResourceAdded(StringHash eventType, VariantMap& eventData);
         void HandleResourceRemoved(StringHash eventType, VariantMap& eventData);

+ 8 - 0
Source/ToolCore/ToolEnvironment.cpp

@@ -74,6 +74,14 @@ bool ToolEnvironment::InitFromPackage()
 
     toolDataDir_ =  resourcesDir + "ToolData/";
 
+    // AtomicNET
+
+    // atomicNETNuGetBinary_ = ToString("%sBuild/Managed/nuget/nuget.exe", rootSourceDir_.CString());
+
+    atomicNETRootDir_ = resourcesDir + "ToolData/AtomicNET/";
+    atomicNETCoreAssemblyDir_ = atomicNETRootDir_ + "Release/";
+    atomicNETManagedPlayerBinary_ = atomicNETCoreAssemblyDir_ + "AtomicPlayer.exe";
+
     return true;
 }