Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
// Copyright 2011-2019 Molecular Matters GmbH, all rights reserved.
|
|
|
|
|
|
|
|
|
|
#include "LC_ClientUserCommandThread.h"
|
|
|
|
|
#include "LC_CommandMap.h"
|
|
|
|
|
#include "LC_DuplexPipeClient.h"
|
|
|
|
|
#include "LC_ClientCommandActions.h"
|
|
|
|
|
#include "LC_Event.h"
|
|
|
|
|
#include "LC_Process.h"
|
|
|
|
|
#include "LC_CriticalSection.h"
|
|
|
|
|
#include "LC_StringUtil.h"
|
|
|
|
|
#include <deque>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace userCommands
|
|
|
|
|
{
|
|
|
|
|
struct Scope
|
|
|
|
|
{
|
|
|
|
|
enum Enum
|
|
|
|
|
{
|
|
|
|
|
NONE,
|
|
|
|
|
ENABLE_MODULES,
|
|
|
|
|
DISABLE_MODULES,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct BaseCommand
|
|
|
|
|
{
|
|
|
|
|
explicit BaseCommand(Scope::Enum scope)
|
|
|
|
|
: m_scope(scope)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~BaseCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) = 0;
|
|
|
|
|
|
|
|
|
|
inline Scope::Enum GetScope(void) const
|
|
|
|
|
{
|
|
|
|
|
return m_scope;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Scope::Enum m_scope;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct EnableModuleCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
EnableModuleCommand(void)
|
|
|
|
|
: BaseCommand(Scope::ENABLE_MODULES)
|
2019-05-14 18:08:06 -04:00
|
|
|
, token(nullptr)
|
|
|
|
|
, moduleName()
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~EnableModuleCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::EnableModule serverCommand;
|
|
|
|
|
serverCommand.processId = process::GetId();
|
|
|
|
|
wcscpy_s(serverCommand.path, moduleName.c_str());
|
|
|
|
|
serverCommand.token = token;
|
|
|
|
|
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Event* token;
|
|
|
|
|
std::wstring moduleName;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct EnableAllModulesCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
EnableAllModulesCommand(void)
|
|
|
|
|
: BaseCommand(Scope::ENABLE_MODULES)
|
2019-05-14 18:08:06 -04:00
|
|
|
, token(nullptr)
|
|
|
|
|
, moduleName()
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~EnableAllModulesCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::EnableAllModules serverCommand;
|
|
|
|
|
serverCommand.processId = process::GetId();
|
|
|
|
|
wcscpy_s(serverCommand.path, moduleName.c_str());
|
|
|
|
|
serverCommand.token = token;
|
|
|
|
|
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Event* token;
|
|
|
|
|
std::wstring moduleName;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct DisableModuleCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
DisableModuleCommand(void)
|
|
|
|
|
: BaseCommand(Scope::DISABLE_MODULES)
|
2019-05-14 18:08:06 -04:00
|
|
|
, token(nullptr)
|
|
|
|
|
, moduleName()
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~DisableModuleCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::DisableModule serverCommand;
|
|
|
|
|
serverCommand.processId = process::GetId();
|
|
|
|
|
wcscpy_s(serverCommand.path, moduleName.c_str());
|
|
|
|
|
serverCommand.token = token;
|
|
|
|
|
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Event* token;
|
|
|
|
|
std::wstring moduleName;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct DisableAllModulesCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
DisableAllModulesCommand(void)
|
|
|
|
|
: BaseCommand(Scope::DISABLE_MODULES)
|
2019-05-14 18:08:06 -04:00
|
|
|
, token(nullptr)
|
|
|
|
|
, moduleName()
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~DisableAllModulesCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::DisableAllModules serverCommand;
|
|
|
|
|
serverCommand.processId = process::GetId();
|
|
|
|
|
wcscpy_s(serverCommand.path, moduleName.c_str());
|
|
|
|
|
serverCommand.token = token;
|
|
|
|
|
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Event* token;
|
|
|
|
|
std::wstring moduleName;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct TriggerRecompileCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
TriggerRecompileCommand(void)
|
|
|
|
|
: BaseCommand(Scope::NONE)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~TriggerRecompileCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::TriggerRecompile serverCommand;
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// BEGIN EPIC MOD - Adding ShowConsole command
|
|
|
|
|
struct ShowConsoleCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
ShowConsoleCommand(void)
|
|
|
|
|
: BaseCommand(Scope::NONE)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~ShowConsoleCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::ShowConsole serverCommand;
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
|
|
|
|
|
// BEGIN EPIC MOD - Adding SetVisible command
|
|
|
|
|
struct SetVisibleCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
SetVisibleCommand(void)
|
|
|
|
|
: BaseCommand(Scope::NONE)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~SetVisibleCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::SetVisible serverCommand;
|
|
|
|
|
serverCommand.visible = visible;
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool visible;
|
|
|
|
|
};
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
|
|
|
|
|
// BEGIN EPIC MOD - Adding SetActive command
|
|
|
|
|
struct SetActiveCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
SetActiveCommand(void)
|
|
|
|
|
: BaseCommand(Scope::NONE)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~SetActiveCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::SetActive serverCommand;
|
|
|
|
|
serverCommand.active = active;
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool active;
|
|
|
|
|
};
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
|
|
|
|
|
// BEGIN EPIC MOD - Adding SetActive command
|
|
|
|
|
struct SetBuildArgumentsCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
SetBuildArgumentsCommand(void)
|
|
|
|
|
: BaseCommand(Scope::NONE)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~SetBuildArgumentsCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::SetBuildArguments serverCommand;
|
|
|
|
|
serverCommand.processId = process::GetId();
|
|
|
|
|
wcscpy_s(serverCommand.arguments, arguments.c_str());
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::wstring arguments;
|
|
|
|
|
};
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
|
2019-03-18 18:06:51 -04:00
|
|
|
// BEGIN EPIC MOD - Support for lazy-loading modules
|
|
|
|
|
struct EnableLazyLoadedModuleCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
EnableLazyLoadedModuleCommand(void)
|
|
|
|
|
: BaseCommand(Scope::NONE)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~EnableLazyLoadedModuleCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::EnableLazyLoadedModule serverCommand;
|
|
|
|
|
serverCommand.processId = process::GetId();
|
|
|
|
|
wcscpy_s(serverCommand.fileName, fileName.c_str());
|
|
|
|
|
serverCommand.moduleBase = moduleBase;
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::wstring fileName;
|
|
|
|
|
Windows::HMODULE moduleBase;
|
|
|
|
|
};
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
|
|
|
|
|
struct BuildPatchCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
BuildPatchCommand(void)
|
|
|
|
|
: BaseCommand(Scope::NONE)
|
2019-05-14 18:08:06 -04:00
|
|
|
, count(0u)
|
|
|
|
|
, moduleNames()
|
|
|
|
|
, objPaths()
|
2019-05-14 18:08:51 -04:00
|
|
|
, amalgamatedObjPaths()
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~BuildPatchCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::BuildPatch serverCommand;
|
|
|
|
|
serverCommand.count = count;
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0u; i < count; ++i)
|
|
|
|
|
{
|
|
|
|
|
commands::BuildPatchPacket packet;
|
|
|
|
|
wcscpy_s(packet.moduleName, moduleNames[i].c_str());
|
|
|
|
|
wcscpy_s(packet.objPath, objPaths[i].c_str());
|
2019-05-14 18:08:51 -04:00
|
|
|
wcscpy_s(packet.amalgamatedObjPath, amalgamatedObjPaths[i].c_str());
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
|
|
|
|
|
pipe->SendCommandAndWaitForAck(packet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int count;
|
|
|
|
|
std::vector<std::wstring> moduleNames;
|
|
|
|
|
std::vector<std::wstring> objPaths;
|
2019-05-14 18:08:51 -04:00
|
|
|
std::vector<std::wstring> amalgamatedObjPaths;
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ApplySettingBoolCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
ApplySettingBoolCommand(void)
|
|
|
|
|
: BaseCommand(Scope::NONE)
|
2019-05-14 18:08:06 -04:00
|
|
|
, settingName()
|
|
|
|
|
, value(0)
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~ApplySettingBoolCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::ApplySettingBool serverCommand;
|
|
|
|
|
strcpy_s(serverCommand.settingName, settingName.c_str());
|
|
|
|
|
serverCommand.settingValue = value;
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string settingName;
|
|
|
|
|
int value;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ApplySettingIntCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
ApplySettingIntCommand(void)
|
|
|
|
|
: BaseCommand(Scope::NONE)
|
2019-05-14 18:08:06 -04:00
|
|
|
, settingName()
|
|
|
|
|
, value(0)
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~ApplySettingIntCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::ApplySettingInt serverCommand;
|
|
|
|
|
strcpy_s(serverCommand.settingName, settingName.c_str());
|
|
|
|
|
serverCommand.settingValue = value;
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string settingName;
|
|
|
|
|
int value;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ApplySettingStringCommand : public BaseCommand
|
|
|
|
|
{
|
|
|
|
|
ApplySettingStringCommand(void)
|
|
|
|
|
: BaseCommand(Scope::NONE)
|
2019-05-14 18:08:06 -04:00
|
|
|
, settingName()
|
|
|
|
|
, value()
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~ApplySettingStringCommand(void) {}
|
|
|
|
|
|
|
|
|
|
virtual void Execute(DuplexPipe* pipe) override
|
|
|
|
|
{
|
|
|
|
|
commands::ApplySettingString serverCommand;
|
|
|
|
|
strcpy_s(serverCommand.settingName, settingName.c_str());
|
|
|
|
|
wcscpy_s(serverCommand.settingValue, value.c_str());
|
|
|
|
|
pipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string settingName;
|
|
|
|
|
std::wstring value;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
// queue for working on commands received by user code
|
|
|
|
|
static std::deque<userCommands::BaseCommand*> g_userCommandQueue;
|
|
|
|
|
static CriticalSection g_userCommandQueueCS;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-11 14:12:36 -04:00
|
|
|
// BEGIN EPIC MOD - Allow manually batching commands
|
|
|
|
|
void BeginCommandBatch()
|
|
|
|
|
{
|
|
|
|
|
g_userCommandQueueCS.Enter();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EndCommandBatch()
|
|
|
|
|
{
|
|
|
|
|
g_userCommandQueueCS.Leave();
|
|
|
|
|
}
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
|
|
|
|
|
ClientUserCommandThread::ClientUserCommandThread(DuplexPipeClient* pipeClient, DuplexPipeClient* exceptionPipeClient)
|
|
|
|
|
: m_thread(INVALID_HANDLE_VALUE)
|
|
|
|
|
, m_processGroupName()
|
|
|
|
|
, m_pipe(pipeClient)
|
|
|
|
|
, m_exceptionPipe(exceptionPipeClient)
|
|
|
|
|
, m_itemInQueueEvent(new Event(nullptr, Event::Type::MANUAL_RESET))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ClientUserCommandThread::~ClientUserCommandThread(void)
|
|
|
|
|
{
|
|
|
|
|
delete m_itemInQueueEvent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int ClientUserCommandThread::Start(const std::wstring& processGroupName, Event* waitForStartEvent, CriticalSection* pipeAccessCS)
|
|
|
|
|
{
|
|
|
|
|
m_processGroupName = processGroupName;
|
|
|
|
|
|
|
|
|
|
// spawn a thread that does the work
|
|
|
|
|
ThreadContext* context = new ThreadContext;
|
|
|
|
|
context->thisInstance = this;
|
|
|
|
|
context->waitForStartEvent = waitForStartEvent;
|
|
|
|
|
context->pipeAccessCS = pipeAccessCS;
|
|
|
|
|
|
|
|
|
|
m_thread = thread::Create(128u * 1024u, &ThreadProxy, context);
|
|
|
|
|
|
|
|
|
|
return thread::GetId(m_thread);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ClientUserCommandThread::Join(void)
|
|
|
|
|
{
|
|
|
|
|
if (m_thread != INVALID_HANDLE_VALUE)
|
|
|
|
|
{
|
|
|
|
|
thread::Join(m_thread);
|
|
|
|
|
thread::Close(m_thread);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void* ClientUserCommandThread::EnableModule(const wchar_t* const nameOfExeOrDll)
|
|
|
|
|
{
|
|
|
|
|
userCommands::EnableModuleCommand* command = new userCommands::EnableModuleCommand;
|
|
|
|
|
command->token = new Event(nullptr, Event::Type::AUTO_RESET);
|
|
|
|
|
command->moduleName = nameOfExeOrDll;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
|
|
|
|
|
return command->token;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void* ClientUserCommandThread::EnableAllModules(const wchar_t* const nameOfExeOrDll)
|
|
|
|
|
{
|
|
|
|
|
userCommands::EnableAllModulesCommand* command = new userCommands::EnableAllModulesCommand;
|
|
|
|
|
command->token = new Event(nullptr, Event::Type::AUTO_RESET);
|
|
|
|
|
command->moduleName = nameOfExeOrDll;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
|
|
|
|
|
return command->token;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void* ClientUserCommandThread::DisableModule(const wchar_t* const nameOfExeOrDll)
|
|
|
|
|
{
|
|
|
|
|
userCommands::DisableModuleCommand* command = new userCommands::DisableModuleCommand;
|
|
|
|
|
command->token = new Event(nullptr, Event::Type::AUTO_RESET);
|
|
|
|
|
command->moduleName = nameOfExeOrDll;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
|
|
|
|
|
return command->token;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void* ClientUserCommandThread::DisableAllModules(const wchar_t* const nameOfExeOrDll)
|
|
|
|
|
{
|
|
|
|
|
userCommands::DisableAllModulesCommand* command = new userCommands::DisableAllModulesCommand;
|
|
|
|
|
command->token = new Event(nullptr, Event::Type::AUTO_RESET);
|
|
|
|
|
command->moduleName = nameOfExeOrDll;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
|
|
|
|
|
return command->token;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ClientUserCommandThread::WaitForToken(void* token)
|
|
|
|
|
{
|
|
|
|
|
Event* event = static_cast<Event*>(token);
|
|
|
|
|
|
|
|
|
|
if (m_thread != INVALID_HANDLE_VALUE)
|
|
|
|
|
{
|
|
|
|
|
// thread was successfully initialized, wait until the command has been executed in the queue
|
|
|
|
|
event->Wait();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete event;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ClientUserCommandThread::TriggerRecompile(void)
|
|
|
|
|
{
|
|
|
|
|
userCommands::TriggerRecompileCommand* command = new userCommands::TriggerRecompileCommand;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-05-14 18:08:51 -04:00
|
|
|
void ClientUserCommandThread::BuildPatch(const wchar_t* moduleNames[], const wchar_t* objPaths[], const wchar_t* amalgamatedObjPaths[], unsigned int count)
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
{
|
|
|
|
|
userCommands::BuildPatchCommand* command = new userCommands::BuildPatchCommand;
|
|
|
|
|
command->count = count;
|
|
|
|
|
command->moduleNames.reserve(count);
|
|
|
|
|
command->objPaths.reserve(count);
|
2019-05-14 18:08:51 -04:00
|
|
|
command->amalgamatedObjPaths.reserve(count);
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
|
|
|
|
|
for (unsigned int i = 0u; i < count; ++i)
|
|
|
|
|
{
|
|
|
|
|
command->moduleNames.push_back(moduleNames[i]);
|
|
|
|
|
command->objPaths.push_back(objPaths[i]);
|
2019-05-14 18:08:51 -04:00
|
|
|
|
|
|
|
|
// the amalgamated object paths are optional
|
|
|
|
|
if (amalgamatedObjPaths && amalgamatedObjPaths[i])
|
|
|
|
|
{
|
|
|
|
|
command->amalgamatedObjPaths.push_back(amalgamatedObjPaths[i]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
command->amalgamatedObjPaths.push_back(std::wstring());
|
|
|
|
|
}
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ClientUserCommandThread::InstallExceptionHandler(void)
|
|
|
|
|
{
|
|
|
|
|
// BEGIN EPIC MOD - Using internal CrashReporter
|
|
|
|
|
// exceptionHandler::Register(this);
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ClientUserCommandThread::ExceptionResult ClientUserCommandThread::HandleException(EXCEPTION_RECORD* exception, CONTEXT* context, unsigned int threadId)
|
|
|
|
|
{
|
|
|
|
|
commands::HandleException serverCommand;
|
|
|
|
|
serverCommand.processId = process::GetId();
|
|
|
|
|
serverCommand.threadId = threadId;
|
|
|
|
|
serverCommand.exception = *exception;
|
|
|
|
|
serverCommand.context = *context;
|
|
|
|
|
serverCommand.clientContextPtr = context;
|
|
|
|
|
|
|
|
|
|
m_exceptionPipe->SendCommandAndWaitForAck(serverCommand);
|
|
|
|
|
|
|
|
|
|
ExceptionResult result = {};
|
|
|
|
|
|
|
|
|
|
CommandMap commandMap;
|
|
|
|
|
commandMap.RegisterAction<actions::HandleExceptionFinished>();
|
|
|
|
|
commandMap.HandleCommands(m_exceptionPipe, &result);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ClientUserCommandThread::End(void)
|
|
|
|
|
{
|
|
|
|
|
// signal to the thread that a new item is in the queue to make it break out of its main loop
|
|
|
|
|
m_itemInQueueEvent->Reset();
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// BEGIN EPIC MOD - Adding ShowConsole command
|
|
|
|
|
void ClientUserCommandThread::ShowConsole()
|
|
|
|
|
{
|
|
|
|
|
userCommands::ShowConsoleCommand* command = new userCommands::ShowConsoleCommand;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
}
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
|
|
|
|
|
// BEGIN EPIC MOD - Adding SetVisible command
|
|
|
|
|
void ClientUserCommandThread::SetVisible(bool visible)
|
|
|
|
|
{
|
|
|
|
|
userCommands::SetVisibleCommand* command = new userCommands::SetVisibleCommand;
|
|
|
|
|
command->visible = visible;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
}
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
|
|
|
|
|
// BEGIN EPIC MOD - Adding SetActive command
|
|
|
|
|
void ClientUserCommandThread::SetActive(bool active)
|
|
|
|
|
{
|
|
|
|
|
userCommands::SetActiveCommand* command = new userCommands::SetActiveCommand;
|
|
|
|
|
command->active = active;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
}
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
|
|
|
|
|
// BEGIN EPIC MOD - Adding SetBuildArguments command
|
|
|
|
|
void ClientUserCommandThread::SetBuildArguments(const wchar_t* arguments)
|
|
|
|
|
{
|
|
|
|
|
userCommands::SetBuildArgumentsCommand* command = new userCommands::SetBuildArgumentsCommand;
|
|
|
|
|
command->arguments = arguments;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
}
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
|
2019-03-18 18:06:51 -04:00
|
|
|
// BEGIN EPIC MOD - Adding support for lazy-loading modules
|
|
|
|
|
void ClientUserCommandThread::EnableLazyLoadedModule(const wchar_t* fileName, Windows::HMODULE moduleBase)
|
|
|
|
|
{
|
|
|
|
|
userCommands::EnableLazyLoadedModuleCommand* command = new userCommands::EnableLazyLoadedModuleCommand;
|
|
|
|
|
command->fileName = fileName;
|
|
|
|
|
command->moduleBase = moduleBase;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
}
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
|
|
|
|
|
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
void ClientUserCommandThread::ApplySettingBool(const char* const settingName, int value)
|
|
|
|
|
{
|
|
|
|
|
userCommands::ApplySettingBoolCommand* command = new userCommands::ApplySettingBoolCommand;
|
|
|
|
|
command->settingName = settingName;
|
|
|
|
|
command->value = value;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ClientUserCommandThread::ApplySettingInt(const char* const settingName, int value)
|
|
|
|
|
{
|
|
|
|
|
userCommands::ApplySettingIntCommand* command = new userCommands::ApplySettingIntCommand;
|
|
|
|
|
command->settingName = settingName;
|
|
|
|
|
command->value = value;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ClientUserCommandThread::ApplySettingString(const char* const settingName, const wchar_t* const value)
|
|
|
|
|
{
|
|
|
|
|
userCommands::ApplySettingStringCommand* command = new userCommands::ApplySettingStringCommand;
|
|
|
|
|
command->settingName = settingName;
|
|
|
|
|
command->value = value;
|
|
|
|
|
{
|
|
|
|
|
CriticalSection::ScopedLock lock(&g_userCommandQueueCS);
|
|
|
|
|
g_userCommandQueue.push_front(command);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// signal to the thread that a new item is in the queue
|
|
|
|
|
m_itemInQueueEvent->Signal();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int __stdcall ClientUserCommandThread::ThreadProxy(void* context)
|
|
|
|
|
{
|
|
|
|
|
thread::SetName("Live coding user commands");
|
|
|
|
|
|
|
|
|
|
ThreadContext* realContext = static_cast<ThreadContext*>(context);
|
|
|
|
|
const unsigned int exitCode = realContext->thisInstance->ThreadFunction(realContext->waitForStartEvent, realContext->pipeAccessCS);
|
|
|
|
|
|
|
|
|
|
delete realContext;
|
|
|
|
|
|
|
|
|
|
return exitCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-03-11 14:31:39 -04:00
|
|
|
// BEGIN EPIC MOD - Temporarily release lock to prevent hangs
|
|
|
|
|
class LeaveableScopedLock
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit LeaveableScopedLock(CriticalSection* cs)
|
|
|
|
|
: m_cs(cs)
|
|
|
|
|
, m_hasLock(true)
|
|
|
|
|
{
|
|
|
|
|
cs->Enter();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Enter()
|
|
|
|
|
{
|
|
|
|
|
if (!m_hasLock)
|
|
|
|
|
{
|
|
|
|
|
m_cs->Enter();
|
|
|
|
|
m_hasLock = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Leave()
|
|
|
|
|
{
|
|
|
|
|
if (m_hasLock)
|
|
|
|
|
{
|
|
|
|
|
m_cs->Leave();
|
|
|
|
|
m_hasLock = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~LeaveableScopedLock(void)
|
|
|
|
|
{
|
|
|
|
|
Leave();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
CriticalSection* m_cs;
|
|
|
|
|
bool m_hasLock;
|
|
|
|
|
};
|
|
|
|
|
// END EPIC MOD
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
unsigned int ClientUserCommandThread::ThreadFunction(Event* waitForStartEvent, CriticalSection* pipeAccessCS)
|
|
|
|
|
{
|
|
|
|
|
// wait until we get the signal that the thread can start
|
|
|
|
|
waitForStartEvent->Wait();
|
|
|
|
|
|
|
|
|
|
CommandMap moduleCommandMap;
|
|
|
|
|
moduleCommandMap.RegisterAction<actions::GetModule>();
|
|
|
|
|
moduleCommandMap.RegisterAction<actions::EnableModuleFinished>();
|
|
|
|
|
moduleCommandMap.RegisterAction<actions::EnableAllModulesFinished>();
|
|
|
|
|
moduleCommandMap.RegisterAction<actions::DisableModuleFinished>();
|
|
|
|
|
moduleCommandMap.RegisterAction<actions::DisableAllModulesFinished>();
|
|
|
|
|
|
|
|
|
|
// those commands are needed when loading compiled patches into spawned executables
|
|
|
|
|
moduleCommandMap.RegisterAction<actions::LoadPatch>();
|
|
|
|
|
moduleCommandMap.RegisterAction<actions::UnloadPatch>();
|
|
|
|
|
moduleCommandMap.RegisterAction<actions::EnterSyncPoint>();
|
|
|
|
|
moduleCommandMap.RegisterAction<actions::LeaveSyncPoint>();
|
|
|
|
|
moduleCommandMap.RegisterAction<actions::CallEntryPoint>();
|
|
|
|
|
moduleCommandMap.RegisterAction<actions::CallHooks>();
|
|
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
|
{
|
|
|
|
|
// wait for event that signals that something is in the queue
|
|
|
|
|
m_itemInQueueEvent->Wait();
|
|
|
|
|
|
|
|
|
|
if (!m_pipe->IsValid())
|
|
|
|
|
{
|
|
|
|
|
// BEGIN EPIC MOD - Using internal CrashReporter
|
|
|
|
|
// // pipe was closed or is broken, bail out
|
|
|
|
|
// exceptionHandler::Unregister();
|
|
|
|
|
// END EPIC MOD - Using internal CrashReporter
|
|
|
|
|
return 1u;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// lock critical section for accessing the pipe.
|
|
|
|
|
// we need to make sure that other threads talking through the pipe don't use it at the same time.
|
|
|
|
|
CriticalSection::ScopedLock pipeLock(pipeAccessCS);
|
|
|
|
|
|
|
|
|
|
// lock critical section for accessing the queue.
|
|
|
|
|
// user code might be calling other exported functions in the mean time.
|
2019-03-11 14:31:39 -04:00
|
|
|
// BEGIN EPIC MOD - Rearrange lock scope to prevent hangs
|
|
|
|
|
LeaveableScopedLock queueLock(&g_userCommandQueueCS);
|
|
|
|
|
// END EPIC MOD
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
|
|
|
|
|
if (g_userCommandQueue.size() == 0u)
|
|
|
|
|
{
|
|
|
|
|
// BEGIN EPIC MOD - Using internal CrashReporter
|
|
|
|
|
// // no new item available, bail out
|
|
|
|
|
// exceptionHandler::Unregister();
|
|
|
|
|
// END EPIC MOD - Using internal CrashReporter
|
|
|
|
|
return 2u;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// separate commands into three groups: ones that need to be scoped for enabling modules, the ones that
|
|
|
|
|
// need to be scoped for disabling modules, and the others that don't need to be scoped at all
|
|
|
|
|
std::vector<userCommands::BaseCommand*> enabledScopedCommands;
|
|
|
|
|
enabledScopedCommands.reserve(g_userCommandQueue.size());
|
|
|
|
|
|
|
|
|
|
std::vector<userCommands::BaseCommand*> disableScopedCommands;
|
|
|
|
|
disableScopedCommands.reserve(g_userCommandQueue.size());
|
|
|
|
|
|
|
|
|
|
std::vector<userCommands::BaseCommand*> commands;
|
|
|
|
|
commands.reserve(g_userCommandQueue.size());
|
|
|
|
|
|
|
|
|
|
while (g_userCommandQueue.size() > 0u)
|
|
|
|
|
{
|
|
|
|
|
userCommands::BaseCommand* command = g_userCommandQueue.back();
|
|
|
|
|
g_userCommandQueue.pop_back();
|
|
|
|
|
|
|
|
|
|
if (command->GetScope() == userCommands::Scope::NONE)
|
|
|
|
|
{
|
|
|
|
|
commands.push_back(command);
|
|
|
|
|
}
|
|
|
|
|
else if (command->GetScope() == userCommands::Scope::ENABLE_MODULES)
|
|
|
|
|
{
|
|
|
|
|
enabledScopedCommands.push_back(command);
|
|
|
|
|
}
|
|
|
|
|
else if (command->GetScope() == userCommands::Scope::DISABLE_MODULES)
|
|
|
|
|
{
|
|
|
|
|
disableScopedCommands.push_back(command);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-11 14:31:39 -04:00
|
|
|
// BEGIN EPIC MOD - Temporarily release lock to prevent hangs
|
|
|
|
|
queueLock.Leave();
|
|
|
|
|
// BEGIN EPIC MOD - Pre
|
|
|
|
|
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
// send out scoped commands first
|
|
|
|
|
{
|
|
|
|
|
const size_t count = enabledScopedCommands.size();
|
|
|
|
|
if (count != 0u)
|
|
|
|
|
{
|
|
|
|
|
m_pipe->SendCommandAndWaitForAck(commands::EnableModuleBatchBegin {});
|
|
|
|
|
|
|
|
|
|
for (size_t i=0u; i < count; ++i)
|
|
|
|
|
{
|
|
|
|
|
userCommands::BaseCommand* command = enabledScopedCommands[i];
|
|
|
|
|
command->Execute(m_pipe);
|
|
|
|
|
|
|
|
|
|
moduleCommandMap.HandleCommands(m_pipe, nullptr);
|
|
|
|
|
|
|
|
|
|
delete command;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pipe->SendCommandAndWaitForAck(commands::EnableModuleBatchEnd {});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const size_t count = disableScopedCommands.size();
|
|
|
|
|
if (count != 0u)
|
|
|
|
|
{
|
|
|
|
|
m_pipe->SendCommandAndWaitForAck(commands::DisableModuleBatchBegin{});
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0u; i < count; ++i)
|
|
|
|
|
{
|
|
|
|
|
userCommands::BaseCommand* command = disableScopedCommands[i];
|
|
|
|
|
command->Execute(m_pipe);
|
|
|
|
|
|
|
|
|
|
moduleCommandMap.HandleCommands(m_pipe, nullptr);
|
|
|
|
|
|
|
|
|
|
delete command;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pipe->SendCommandAndWaitForAck(commands::DisableModuleBatchEnd{});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// send out non-scoped commands second
|
|
|
|
|
{
|
|
|
|
|
const size_t count = commands.size();
|
|
|
|
|
for (size_t i = 0u; i < count; ++i)
|
|
|
|
|
{
|
|
|
|
|
userCommands::BaseCommand* command = commands[i];
|
|
|
|
|
command->Execute(m_pipe);
|
|
|
|
|
|
|
|
|
|
delete command;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-11 14:31:39 -04:00
|
|
|
// BEGIN EPIC MOD - Temporarily release lock to prevent hangs
|
|
|
|
|
queueLock.Enter();
|
|
|
|
|
if(g_userCommandQueue.size() > 0)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// BEGIN EPIC MOD
|
|
|
|
|
|
Integrating live coding feature (aka Live++) into UE4.
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
2019-03-05 15:54:02 -05:00
|
|
|
m_itemInQueueEvent->Reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0u;
|
|
|
|
|
}
|