Browse Source

AtomicEditor can fork as player

Josh Engebretson 10 years ago
parent
commit
ab30058dd5

+ 1 - 1
CMake/Modules/AtomicDesktop.cmake

@@ -3,4 +3,4 @@ include_directories(${CMAKE_SOURCE_DIR}/Source/ThirdParty/Poco/Foundation/includ
 
 
 add_definitions( -DATOMIC_TBUI -DATOMIC_FILEWATCHER -DPOCO_NO_AUTOMATIC_LIBS)
 add_definitions( -DATOMIC_TBUI -DATOMIC_FILEWATCHER -DPOCO_NO_AUTOMATIC_LIBS)
 
 
-set (ATOMIC_LINK_LIBRARIES ${ATOMIC_LINK_LIBRARIES} LibCpuId SQLite TurboBadger)
+set (ATOMIC_LINK_LIBRARIES ${ATOMIC_LINK_LIBRARIES} LibCpuId SQLite TurboBadger SimpleIPC)

+ 21 - 0
Source/Atomic/IPC/IPC.cpp

@@ -0,0 +1,21 @@
+
+#include "IPCBroker.h"
+#include "IPCWorker.h"
+#include "IPC.h"
+
+namespace Atomic
+{
+
+IPC::IPC(Context* context) : Object(context)
+{
+
+}
+
+
+IPC::~IPC()
+{
+
+}
+
+
+}

+ 29 - 0
Source/Atomic/IPC/IPC.h

@@ -0,0 +1,29 @@
+#pragma once
+
+#include "../Core/Object.h"
+
+namespace Atomic
+{
+
+class IPCBroker;
+class IPCWorker;
+
+class IPC : public Object
+{
+    OBJECT(IPC);
+
+public:
+
+    /// Construct.
+    IPC(Context* context);
+    /// Destruct.
+    virtual ~IPC();
+
+private:
+
+    Vector<SharedPtr<IPCBroker> > brokers_;
+    Vector<SharedPtr<IPCWorker> > workers_;
+
+};
+
+}

+ 82 - 2
Source/Atomic/IPC/IPCBroker.cpp

@@ -1,18 +1,98 @@
 
 
+#include "../Core/StringUtils.h"
+#include "../IO/Log.h"
+
 #include "IPCBroker.h"
 #include "IPCBroker.h"
 
 
+#include <SimpleIPC/ipc_channel.h>
+#include <SimpleIPC/ipc_codec.h>
+#include <SimpleIPC/ipc_msg_dispatch.h>
+
+typedef ipc::Channel<PipeTransport, ipc::Encoder, ipc::Decoder> PipeChannel;
+
 namespace Atomic
 namespace Atomic
 {
 {
 
 
-IPCBroker::IPCBroker(Context* context) : Object(context)
+IPCBroker::IPCBroker(Context* context) : Object(context),
+    pp_(true),
+    workerHandle_(0)
 {
 {
 
 
 }
 }
 
 
-
 IPCBroker::~IPCBroker()
 IPCBroker::~IPCBroker()
 {
 {
 
 
 }
 }
 
 
+void IPCBroker::ThreadFunction()
+{
+    //PipeChannel channel(&transport);
+
+    while (shouldRun_)
+    {
+        int answer;
+        size_t sz = sizeof(int);
+        transport_.Read(&answer, &sz);
+        if (sz == sizeof(int))
+        {
+            shouldRun_ = false;
+        }
+    }
+
+}
+
+bool IPCBroker::SpawnWorker(const String& command, const Vector<String>& args, const String& initialDirectory)
+{
+    Poco::Process::Env env;
+    return SpawnWorker(command, args, initialDirectory, env);
+}
+
+bool IPCBroker::SpawnWorker(const String& command, const Vector<String>& args, const String& initialDirectory, const Poco::Process::Env& env)
+{
+
+    if (!transport_.OpenServer(pp_.fd1()))
+    {
+        return false;
+    }
+
+    Poco::Process::Args pargs;
+
+    for (unsigned i = 0; i < args.Size(); i++)
+        pargs.push_back(args[i].CString());
+
+#ifdef ATOMIC_PLATFORM_WINDOWS
+    // fd2 with be a HANDLE on windows
+    /*
+        wchar_t pipe_num[10];
+        _i64tow_s(reinterpret_cast<__int64>(pp.fd2()), pipe_num, sizeof(pipe_num)/sizeof(pipe_num[0]), 10);
+        writable_cmdline += kCmdLinePipeEq + std::wstring(pipe_num);
+    */
+#else
+    String ipc = ToString("--ipc-server=%i", pp_.fd1());
+    pargs.push_back(ipc.CString());
+    ipc = ToString("--ipc-client=%i", pp_.fd2());
+    pargs.push_back(ipc.CString());
+#endif
+
+    // socket pair only works same binary, have AtomicEditor be able to double as player?
+    // this could be cool, as AtomicEditor could have some machinery that is left out of
+    // the deployment player, and could simplify the cli (relaunch editor in player mode)
+
+
+    std::string pcommand = command.CString();
+    std::string pinitialDirectory = initialDirectory.CString();
+
+    workerHandle_ = new Poco::ProcessHandle(Poco::Process::launch(pcommand, pargs, pinitialDirectory, NULL, NULL, NULL, env));
+
+    if (!Poco::Process::isRunning(*workerHandle_))
+        return false;
+
+    close(pp_.fd2());
+
+    return Run();
+
+}
+
+
 }
 }

+ 13 - 0
Source/Atomic/IPC/IPCBroker.h

@@ -1,6 +1,7 @@
 
 
 #pragma once
 #pragma once
 
 
+#include <Poco/Process.h>
 #include <SimpleIPC/ipc_pipe.h>
 #include <SimpleIPC/ipc_pipe.h>
 
 
 #include "../Core/Mutex.h"
 #include "../Core/Mutex.h"
@@ -20,6 +21,18 @@ public:
     /// Destruct.
     /// Destruct.
     virtual ~IPCBroker();
     virtual ~IPCBroker();
 
 
+    void ThreadFunction();
+
+    bool SpawnWorker(const String& command, const Vector<String>& args, const String& initialDirectory = "");
+    bool SpawnWorker(const String& command, const Vector<String>& args, const String& initialDirectory, const Poco::Process::Env& env);
+
+private:
+
+    PipeTransport transport_;
+    PipePair pp_;
+
+    Poco::ProcessHandle* workerHandle_;
+
 };
 };
 
 
 }
 }

+ 44 - 0
Source/Atomic/IPC/IPCWorker.cpp

@@ -0,0 +1,44 @@
+
+#include "IPCWorker.h"
+
+#include "../IO/Log.h"
+
+#include <SimpleIPC/ipc_channel.h>
+#include <SimpleIPC/ipc_codec.h>
+#include <SimpleIPC/ipc_msg_dispatch.h>
+
+namespace Atomic
+{
+
+IPCWorker::IPCWorker(int fd, Context* context) : Object(context),
+    fd_(fd)
+{
+
+}
+
+IPCWorker::~IPCWorker()
+{
+
+}
+
+void IPCWorker::ThreadFunction()
+{
+
+    PipeTransport transport;
+
+    if (!transport.OpenClient(fd_))
+    {
+        LOGERRORF("Unable to open IPC transport fd = %i", fd_);
+        shouldRun_ = false;
+        return;
+    }
+
+    int answer = 42;
+    size_t sz = sizeof(int);
+    transport.Write(&answer, sz);
+
+    LOGERRORF("Wrote to IPC transport fd = %i", fd_);
+
+}
+
+}

+ 31 - 0
Source/Atomic/IPC/IPCWorker.h

@@ -0,0 +1,31 @@
+
+#pragma once
+
+#include <SimpleIPC/ipc_pipe.h>
+
+#include "../Core/Mutex.h"
+#include "../Core/Thread.h"
+#include "../Core/Object.h"
+
+namespace Atomic
+{
+
+class IPCWorker : public Object, public Thread
+{
+    OBJECT(IPCWorker);
+
+public:
+    /// Construct.
+    IPCWorker(int fd, Context* context);
+    /// Destruct.
+    virtual ~IPCWorker();
+
+    void ThreadFunction();
+
+private:
+
+    int fd_;
+
+};
+
+}

+ 0 - 2
Source/AtomicEditor/Source/AEApplication.cpp

@@ -48,8 +48,6 @@
 #include <ToolCore/ToolSystem.h>
 #include <ToolCore/ToolSystem.h>
 #include <ToolCore/ToolEnvironment.h>
 #include <ToolCore/ToolEnvironment.h>
 
 
-DEFINE_APPLICATION_MAIN(AtomicEditor::AEApplication);
-
 using namespace ToolCore;
 using namespace ToolCore;
 
 
 namespace AtomicEditor
 namespace AtomicEditor

+ 89 - 0
Source/AtomicEditor/Source/Main.cpp

@@ -0,0 +1,89 @@
+
+#if defined(WIN32) && !defined(ATOMIC_WIN32_CONSOLE)
+#include <Atomic/Core/MiniDump.h>
+#include <windows.h>
+#ifdef _MSC_VER
+#include <crtdbg.h>
+#endif
+#endif
+
+#include <Atomic/Core/ProcessUtils.h>
+#include <Atomic/IO/Log.h>
+
+#include "AEApplication.h"
+#include "Player/AEPlayerApplication.h"
+
+using namespace AtomicEditor;
+
+static int RunEditorApplication()
+{
+    Atomic::SharedPtr<Atomic::Context> context(new Atomic::Context());
+    Atomic::SharedPtr<AEApplication> application(new AEApplication(context));
+    return application->Run();
+}
+
+static int RunPlayerApplication()
+{
+    Atomic::SharedPtr<Atomic::Context> context(new Atomic::Context());
+    Atomic::SharedPtr<AEPlayerApplication> application(new AEPlayerApplication(context));
+    return application->Run();
+}
+
+
+// Define a platform-specific main function, which in turn executes the user-defined function
+
+// MSVC debug mode: use memory leak reporting
+#if defined(_MSC_VER) && defined(_DEBUG) && !defined(ATOMIC_WIN32_CONSOLE)
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
+{
+    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+    Atomic::ParseArguments(GetCommandLineW());
+    return function;
+}
+// MSVC release mode: write minidump on crash
+#elif defined(_MSC_VER) && defined(ATOMIC_MINIDUMPS) && !defined(ATOMIC_WIN32_CONSOLE)
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
+{
+    Atomic::ParseArguments(GetCommandLineW());
+    int exitCode;
+    __try
+    {
+        exitCode = function;
+    }
+    __except(Atomic::WriteMiniDump("Atomic", GetExceptionInformation()))
+    {
+    }
+    return exitCode;
+}
+// Other Win32 or minidumps disabled: just execute the function
+#elif defined(WIN32) && !defined(ATOMIC_WIN32_CONSOLE)
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
+{
+    Atomic::ParseArguments(GetCommandLineW());
+    return function;
+}
+// Linux or OS X: use main
+#else
+int main(int argc, char** argv)
+{
+    Atomic::ParseArguments(argc, argv);
+
+    const Vector<String>& arguments = GetArguments();
+
+    bool runPlayer = false;
+    for (unsigned i = 0; i < arguments.Size();i++)
+    {
+        if (arguments.At(i) == "--player")
+        {
+            runPlayer = true;
+            break;
+        }
+    }
+
+    if (runPlayer)
+        return RunPlayerApplication();
+
+    return RunEditorApplication();
+}
+#endif

+ 15 - 5
Source/AtomicEditor/Source/Player/AEPlayer.cpp

@@ -7,13 +7,13 @@
 #include "../Subprocess/AESubprocessSystem.h"
 #include "../Subprocess/AESubprocessSystem.h"
 
 
 #include <Atomic/Core/Context.h>
 #include <Atomic/Core/Context.h>
+#include <Atomic/Core/StringUtils.h>
 #include <Atomic/IO/FileSystem.h>
 #include <Atomic/IO/FileSystem.h>
 #include <Atomic/Input/Input.h>
 #include <Atomic/Input/Input.h>
 #include <Atomic/Resource/ResourceCache.h>
 #include <Atomic/Resource/ResourceCache.h>
 #include <Atomic/UI/UI.h>
 #include <Atomic/UI/UI.h>
-#include <AtomicJS/Javascript/Javascript.h>
-#include <AtomicJS/Javascript/JSVM.h>
-#include <AtomicJS/Javascript/JSEvents.h>
+
+#include <Atomic/IPC/IPCBroker.h>
 
 
 #include <ToolCore/ToolEnvironment.h>
 #include <ToolCore/ToolEnvironment.h>
 
 
@@ -60,9 +60,9 @@ void AEPlayer::HandleJSError(StringHash eventType, VariantMap& eventData)
 bool AEPlayer::Play(AEPlayerMode mode, const IntRect &rect)
 bool AEPlayer::Play(AEPlayerMode mode, const IntRect &rect)
 {
 {
     ToolCore::ToolEnvironment* env = GetSubsystem<ToolCore::ToolEnvironment>();
     ToolCore::ToolEnvironment* env = GetSubsystem<ToolCore::ToolEnvironment>();
-    const String& playerBinary = env->GetPlayerBinary();
+    const String& editorBinary = env->GetEditorBinary();
 
 
-    SubprocessSystem* system = GetSubsystem<SubprocessSystem>();
+    IPCBroker* broker = new IPCBroker(context_);
 
 
     Vector<String> paths;
     Vector<String> paths;
     paths.Push(env->GetCoreDataDir());
     paths.Push(env->GetCoreDataDir());
@@ -74,9 +74,19 @@ bool AEPlayer::Play(AEPlayerMode mode, const IntRect &rect)
     Vector<String> vargs;
     Vector<String> vargs;
 
 
     String args = ToString("--editor-resource-paths \"%s\"", resourcePaths.CString());
     String args = ToString("--editor-resource-paths \"%s\"", resourcePaths.CString());
+
+
     vargs = args.Split(' ');
     vargs = args.Split(' ');
+    vargs.Insert(0, "--player");
+
+    broker->SpawnWorker(editorBinary, vargs);
+
+    /*
+    SubprocessSystem* system = GetSubsystem<SubprocessSystem>();
+
 
 
     system->Launch(playerBinary, vargs);
     system->Launch(playerBinary, vargs);
+    */
 
 
     return false;
     return false;
 }
 }

+ 1 - 3
Source/AtomicEditor/Source/Player/AEPlayer.h

@@ -63,9 +63,7 @@ private:
     void HandleJSError(StringHash eventType, VariantMap& eventData);
     void HandleJSError(StringHash eventType, VariantMap& eventData);
     void HandleEditorShutdown(StringHash eventType, VariantMap& eventData);
     void HandleEditorShutdown(StringHash eventType, VariantMap& eventData);
 
 
-    SharedPtr<UIPlayer> uiPlayer_;
-
-    SharedPtr<JSVM> vm_;
+    SharedPtr<UIPlayer> uiPlayer_;    
 
 
 };
 };
 
 

+ 182 - 0
Source/AtomicEditor/Source/Player/AEPlayerApplication.cpp

@@ -0,0 +1,182 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// 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/Atomic.h>
+#include <Atomic/Engine/Engine.h>
+#include <Atomic/IO/FileSystem.h>
+#include <Atomic/IO/Log.h>
+#include <Atomic/Core/Main.h>
+#include <Atomic/Core/ProcessUtils.h>
+#include <Atomic/Resource/ResourceCache.h>
+#include <Atomic/Resource/ResourceEvents.h>
+
+#include <Atomic/IPC/IPCWorker.h>
+
+// Move me
+#include <Atomic/Environment/Environment.h>
+
+#include <AtomicJS/Javascript/Javascript.h>
+
+#include "AEPlayerApplication.h"
+
+#include <Atomic/DebugNew.h>
+
+#include <Atomic/UI/UI.h>
+
+#ifdef __APPLE__
+#include <unistd.h>
+#endif
+
+namespace AtomicEditor
+{
+
+// fixme
+static JSVM* vm = NULL;
+static Javascript* javascript = NULL;
+
+AEPlayerApplication::AEPlayerApplication(Context* context) :
+    Application(context)
+{
+#ifdef ATOMIC_3D
+    RegisterEnvironmentLibrary(context_);
+#endif
+}
+
+void AEPlayerApplication::Setup()
+{
+    FileSystem* filesystem = GetSubsystem<FileSystem>();
+
+    engineParameters_["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_["ResourcePaths"] = "AtomicResources";
+    engineParameters_["FullScreen"] = false;
+    engineParameters_["WindowWidth"] = 1280;
+    engineParameters_["WindowHeight"] = 720;
+#endif
+
+#if ATOMIC_PLATFORM_WINDOWS
+    engineParameters_["WindowIcon"] = "Images/AtomicLogo32.png";
+    engineParameters_["ResourcePrefixPath"] = "AtomicPlayer_Resources";
+#elif ATOMIC_PLATFORM_ANDROID
+    //engineParameters_["ResourcePrefixPath"] = "assets";
+#elif ATOMIC_PLATFORM_OSX
+    engineParameters_["ResourcePrefixPath"] = "../Resources";
+#endif
+
+    const Vector<String>& arguments = GetArguments();
+
+    int ipc_server_fd = -1;
+    int ipc_client_fd = -1;
+
+    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;
+
+            LOGERRORF("Starting IPCWorker %s", argument.CString());
+            if (argument.StartsWith("--ipc-server=") || argument.StartsWith("--ipc-client="))
+            {
+
+                Vector<String> ipc = argument.Split(argument.CString(), '=');
+                if (ipc.Size() == 2)
+                {
+                    int fd = ToInt(ipc[1].CString());
+                    if (argument.StartsWith("--ipc-server="))
+                        ipc_server_fd = fd;
+                    else
+                    {
+
+                        ipc_client_fd = fd;
+                        close(ipc_server_fd);
+                        IPCWorker* worker = new IPCWorker(ipc_client_fd, context_);
+                        worker->Run();
+                    }
+
+                }
+
+            }
+            else if (argument == "--editor-resource-paths" && value.Length())
+            {
+                engineParameters_["ResourcePrefixPath"] = "";
+                value.Replace("!", ";");
+                engineParameters_["ResourcePaths"] = value;
+            }
+        }
+    }
+
+    // Use the script file name as the base name for the log file
+    engineParameters_["LogName"] = filesystem->GetAppPreferencesDir("AtomicPlayer", "Logs") + "AtomicPlayer.log";
+}
+
+void AEPlayerApplication::Start()
+{
+
+    // Instantiate and register the Javascript subsystem
+    javascript = new Javascript(context_);
+    context_->RegisterSubsystem(javascript);
+
+    vm = javascript->InstantiateVM("MainVM");
+    vm->InitJSContext();
+
+    vm->SetModuleSearchPath("Modules");
+
+    if (!vm->ExecuteMain())
+    {
+        ErrorExit("Error executing Scripts/main.js");
+    }
+
+    return;
+}
+
+void AEPlayerApplication::Stop()
+{
+    context_->RemoveSubsystem<Javascript>();
+}
+
+void AEPlayerApplication::HandleScriptReloadStarted(StringHash eventType, VariantMap& eventData)
+{
+}
+
+void AEPlayerApplication::HandleScriptReloadFinished(StringHash eventType, VariantMap& eventData)
+{
+}
+
+void AEPlayerApplication::HandleScriptReloadFailed(StringHash eventType, VariantMap& eventData)
+{
+    ErrorExit();
+}
+
+}

+ 57 - 0
Source/AtomicEditor/Source/Player/AEPlayerApplication.h

@@ -0,0 +1,57 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// 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 <Atomic/Engine/Application.h>
+
+using namespace Atomic;
+
+namespace AtomicEditor
+{
+
+class AEPlayerApplication : public Application
+{
+    OBJECT(AEPlayerApplication);
+
+public:
+    /// Construct.
+    AEPlayerApplication(Context* context);
+
+    /// Setup before engine initialization. Verify that a script file has been specified.
+    virtual void Setup();
+    /// Setup after engine initialization. Load the script and execute its start function.
+    virtual void Start();
+    /// Cleanup after the main loop. Run the script's stop function if it exists.
+    virtual void Stop();
+
+private:
+    /// Handle reload start of the script file.
+    void HandleScriptReloadStarted(StringHash eventType, VariantMap& eventData);
+    /// Handle reload success of the script file.
+    void HandleScriptReloadFinished(StringHash eventType, VariantMap& eventData);
+    /// Handle reload failure of the script file.
+    void HandleScriptReloadFailed(StringHash eventType, VariantMap& eventData);
+
+};
+
+}

+ 7 - 8
Source/AtomicEditor/Source/Subprocess/AESubprocess.cpp

@@ -15,7 +15,7 @@ namespace AtomicEditor
 
 
 Subprocess::Subprocess(Context* context) :
 Subprocess::Subprocess(Context* context) :
     Object(context),
     Object(context),
-    handle_(NULL),
+    processHandle_(NULL),
     inStream_(pipeOut_),
     inStream_(pipeOut_),
     errorStream_(pipeError_),
     errorStream_(pipeError_),
     returnCode_(-1)
     returnCode_(-1)
@@ -25,8 +25,8 @@ Subprocess::Subprocess(Context* context) :
 
 
 Subprocess::~Subprocess()
 Subprocess::~Subprocess()
 {
 {
-    if (handle_)
-        delete handle_;
+    if (processHandle_)
+        delete processHandle_;
 }
 }
 
 
 
 
@@ -37,7 +37,7 @@ void Subprocess::ThreadFunction()
         int read;
         int read;
         char data[129];
         char data[129];
 
 
-        if (!Poco::Process::isRunning(*handle_))
+        if (!Poco::Process::isRunning(*processHandle_))
         {
         {
             shouldRun_ = false;
             shouldRun_ = false;
             break;
             break;
@@ -57,7 +57,7 @@ void Subprocess::ThreadFunction()
 
 
         if (inStream_.eof())
         if (inStream_.eof())
         {
         {
-            returnCode_ = handle_->wait();
+            returnCode_ = processHandle_->wait();
 
 
             if (returnCode_)
             if (returnCode_)
             {
             {
@@ -143,10 +143,9 @@ bool Subprocess::Launch(const String& command, const Vector<String>& args, const
     std::string pcommand = command.CString();
     std::string pcommand = command.CString();
     std::string pinitialDirectory = initialDirectory.CString();
     std::string pinitialDirectory = initialDirectory.CString();
 
 
-    // this can take an ENV as well, may come in useful
-    handle_ = new Poco::ProcessHandle(Poco::Process::launch(pcommand, pargs, pinitialDirectory, &pipeIn_, &pipeOut_, &pipeError_, env));
+    processHandle_ = new Poco::ProcessHandle(Poco::Process::launch(pcommand, pargs, pinitialDirectory, &pipeIn_, &pipeOut_, &pipeError_, env));
 
 
-    if (!Poco::Process::isRunning(*handle_))
+    if (!Poco::Process::isRunning(*processHandle_))
         return false;
         return false;
 
 
     return Run();
     return Run();

+ 1 - 1
Source/AtomicEditor/Source/Subprocess/AESubprocess.h

@@ -58,7 +58,7 @@ private:
     String errorOutput_;
     String errorOutput_;
     int returnCode_;
     int returnCode_;
 
 
-    Poco::ProcessHandle* handle_;
+    Poco::ProcessHandle* processHandle_;
     Poco::Pipe pipeIn_;
     Poco::Pipe pipeIn_;
     Poco::Pipe pipeOut_;
     Poco::Pipe pipeOut_;
     Poco::Pipe pipeError_;
     Poco::Pipe pipeError_;

+ 2 - 2
Source/ThirdParty/SimpleIPC/ipc_codec.h

@@ -86,14 +86,14 @@ public:
 
 
   bool OnString8(const IPCString& s, int tag) {
   bool OnString8(const IPCString& s, int tag) {
     SetHeaderNext(tag | ENC_STRN08);
     SetHeaderNext(tag | ENC_STRN08);
-    PushBack(s.size());
+    PushBack((unsigned int) s.size());
     if (s.size()) AddStr(s);
     if (s.size()) AddStr(s);
     return true;
     return true;
   }
   }
 
 
   bool OnString16(const IPCWString& s, int tag) {
   bool OnString16(const IPCWString& s, int tag) {
     SetHeaderNext(tag | ENC_STRN16);
     SetHeaderNext(tag | ENC_STRN16);
-    PushBack(s.size());
+    PushBack((unsigned int) s.size());
     if (s.size()) AddStr(s);
     if (s.size()) AddStr(s);
     return true;
     return true;
   }
   }

+ 1 - 1
Source/ThirdParty/SimpleIPC/pipe_unix.cpp

@@ -65,7 +65,7 @@ size_t WriteToFD(int fd, const char* data, size_t size) {
 }  // namespace
 }  // namespace
 
 
 
 
-PipePair::PipePair() {
+PipePair::PipePair(bool unused) {
   fd_[0] = -1;
   fd_[0] = -1;
   fd_[1] = -1;
   fd_[1] = -1;
   
   

+ 4 - 1
Source/ThirdParty/SimpleIPC/pipe_unix.h

@@ -21,7 +21,10 @@
 
 
 class PipePair {
 class PipePair {
 public:
 public:
-  PipePair();
+
+  // unused bool so matches windows PipePair constructor
+  // which allows inheriting
+  PipePair(bool unused = false);
   
   
   int fd1() const { return fd_[0]; }
   int fd1() const { return fd_[0]; }
   int fd2() const { return fd_[1]; }
   int fd2() const { return fd_[1]; }

+ 7 - 7
Source/ToolCore/Subprocess/Subprocess.cpp

@@ -13,7 +13,7 @@ namespace ToolCore
 
 
 Subprocess::Subprocess(Context* context) :
 Subprocess::Subprocess(Context* context) :
     Object(context),
     Object(context),
-    handle_(NULL),
+    processHandle_(NULL),
     inStream_(pipeOut_),
     inStream_(pipeOut_),
     errorStream_(pipeError_),
     errorStream_(pipeError_),
     returnCode_(-1)
     returnCode_(-1)
@@ -23,8 +23,8 @@ Subprocess::Subprocess(Context* context) :
 
 
 Subprocess::~Subprocess()
 Subprocess::~Subprocess()
 {
 {
-    if (handle_)
-        delete handle_;
+    if (processHandle_)
+        delete processHandle_;
 }
 }
 
 
 
 
@@ -35,7 +35,7 @@ void Subprocess::ThreadFunction()
         int read;
         int read;
         char data[129];
         char data[129];
 
 
-        if (!Poco::Process::isRunning(*handle_))
+        if (!Poco::Process::isRunning(*processHandle_))
         {
         {
             shouldRun_ = false;
             shouldRun_ = false;
             break;
             break;
@@ -55,7 +55,7 @@ void Subprocess::ThreadFunction()
 
 
         if (inStream_.eof())
         if (inStream_.eof())
         {
         {
-            returnCode_ = handle_->wait();
+            returnCode_ = processHandle_->wait();
 
 
             if (returnCode_)
             if (returnCode_)
             {
             {
@@ -142,9 +142,9 @@ bool Subprocess::Launch(const String& command, const Vector<String>& args, const
     std::string pinitialDirectory = initialDirectory.CString();
     std::string pinitialDirectory = initialDirectory.CString();
 
 
     // this can take an ENV as well, may come in useful
     // this can take an ENV as well, may come in useful
-    handle_ = new Poco::ProcessHandle(Poco::Process::launch(pcommand, pargs, pinitialDirectory, &pipeIn_, &pipeOut_, &pipeError_, env));
+    processHandle_ = new Poco::ProcessHandle(Poco::Process::launch(pcommand, pargs, pinitialDirectory, &pipeIn_, &pipeOut_, &pipeError_, env));
 
 
-    if (!Poco::Process::isRunning(*handle_))
+    if (!Poco::Process::isRunning(*processHandle_))
         return false;
         return false;
 
 
     return Run();
     return Run();

+ 1 - 1
Source/ToolCore/Subprocess/Subprocess.h

@@ -58,7 +58,7 @@ private:
     String errorOutput_;
     String errorOutput_;
     int returnCode_;
     int returnCode_;
 
 
-    Poco::ProcessHandle* handle_;
+    Poco::ProcessHandle* processHandle_;
     Poco::Pipe pipeIn_;
     Poco::Pipe pipeIn_;
     Poco::Pipe pipeOut_;
     Poco::Pipe pipeOut_;
     Poco::Pipe pipeError_;
     Poco::Pipe pipeError_;

+ 1 - 0
Source/ToolCore/ToolEnvironment.cpp

@@ -105,6 +105,7 @@ void ToolEnvironment::SetRootBuildDir(const String& buildDir, bool setBinaryPath
     {
     {
 #ifdef ATOMIC_PLATFORM_OSX
 #ifdef ATOMIC_PLATFORM_OSX
         playerBinary_ = rootBuildDir_ + "Source/AtomicPlayer/AtomicPlayer.app/Contents/MacOS/AtomicPlayer";
         playerBinary_ = rootBuildDir_ + "Source/AtomicPlayer/AtomicPlayer.app/Contents/MacOS/AtomicPlayer";
+        editorBinary_ = rootBuildDir_ + "Source/AtomicEditor/AtomicEditor.app/Contents/MacOS/AtomicEditor";
 #endif
 #endif
     }
     }