Files
TG_ARPG/Plugins/Developer/RiderLink/Source/RiderLink/Private/RiderLink.cpp
2023-07-16 14:29:40 +08:00

133 lines
4.0 KiB
C++

#include "RiderLink.hpp"
#include "ProtocolFactory.h"
#include "UE4Library/UE4Library.Generated.h"
#include "Misc/App.h"
#include "Misc/ScopeRWLock.h"
#include "Modules/ModuleManager.h"
#include "HAL/Platform.h"
#define LOCTEXT_NAMESPACE "RiderLink"
DEFINE_LOG_CATEGORY(FLogRiderLinkModule);
IMPLEMENT_MODULE(FRiderLinkModule, RiderLink);
static FString GetProjectName()
{
FString ProjectNameNoExtension = FApp::GetProjectName();
if (ProjectNameNoExtension.IsEmpty())
ProjectNameNoExtension = TEXT("<ENGINE>");
return ProjectNameNoExtension;
}
void FRiderLinkModule::ShutdownModule()
{
UE_LOG(FLogRiderLinkModule, Verbose, TEXT("RiderLink SHUTDOWN START"));
ModuleLifetimeDef.terminate();
ProtocolFactory.Reset();
UE_LOG(FLogRiderLinkModule, Verbose, TEXT("RiderLink SHUTDOWN FINISH"));
}
void FRiderLinkModule::StartupModule()
{
UE_LOG(FLogRiderLinkModule, Verbose, TEXT("RiderLink STARTUP START"));
ProtocolFactory = MakeUnique<class ProtocolFactory>(GetProjectName());
Scheduler.queue([this]()
{
InitProtocol();
});
UE_LOG(FLogRiderLinkModule, Verbose, TEXT("RiderLink STARTUP FINISH"));
}
void FRiderLinkModule::InitProtocol()
{
WireLifetimeDef = MakeUnique<rd::LifetimeDefinition>(ModuleLifetimeDef.lifetime);
rd::Lifetime WireLifetime = WireLifetimeDef->lifetime;
std::shared_ptr<rd::SocketWire::Server> Wire = ProtocolFactory->CreateWire(&Scheduler, WireLifetime);
Protocol = ProtocolFactory->CreateProtocol(&Scheduler, WireLifetime.create_nested(), Wire);
// Exception fired for Server::Base::~Base() when trying to invoke it this way
// WireLifetime->add_action([this]()
// {
// if (!ModuleLifetimeDef.is_terminated())
// {
// Scheduler.queue([this]()
// {
// InitProtocol();
// });
// }
// });
Protocol->wire->connected.view(WireLifetime, [this](rd::Lifetime ConnectionLifetime, bool const& IsConnected)
{
Scheduler.queue([this, ConnectionLifetime, IsConnected]()
{
if (!IsConnected) return;
FRWScopeLock LockOnConnect(ModelLock, SLT_Write);
EditorModel = MakeUnique<JetBrains::EditorPlugin::RdEditorModel>();
EditorModel->connect(ConnectionLifetime, Protocol.Get());
JetBrains::EditorPlugin::UE4Library::serializersOwner.registerSerializersCore(
EditorModel->get_serialization_context().get_serializers()
);
ConnectionLifetime->add_action([&]() mutable
{
Scheduler.queue([&]()mutable
{
FRWScopeLock LockOnDisconnect(ModelLock, SLT_Write);
RdIsModelAlive.set(false);
});
});
RdIsModelAlive.set(true);
FString projectName = GetProjectName();
FString executableName = FPlatformProcess::ExecutableName(false);
uint32_t pid = FPlatformProcess::GetCurrentProcessId();
std::wstring projectNameWstr = TCHAR_TO_WCHAR(GetData(projectName));
std::wstring executableNameWstr = TCHAR_TO_WCHAR(GetData(executableName));
auto connectionInfo = JetBrains::EditorPlugin::ConnectionInfo(projectNameWstr, executableNameWstr, pid);
EditorModel->get_connectionInfo().set(connectionInfo);
});
});
}
bool FRiderLinkModule::SupportsDynamicReloading() { return true; }
// Can't place RdEditorModel or TUniquePtr<RdEditorModel> into RdProperty.
// Have to resort to RdProperty<bool> and change it before creating new RdEditorModel
void FRiderLinkModule::ViewModel(rd::Lifetime Lifetime,
TFunction<void(rd::Lifetime, JetBrains::EditorPlugin::RdEditorModel const&)> Handler)
{
Scheduler.invoke_or_queue([this, Lifetime, Handler]
{
RdIsModelAlive.view(Lifetime, [this, Handler](rd::Lifetime ModelLifetime, bool const& Cond)
{
if (Cond) Handler(ModelLifetime, *EditorModel.Get());
});
});
}
void FRiderLinkModule::QueueAction(TFunction<void()> Handler)
{
Scheduler.invoke_or_queue([this, Handler]
{
Handler();
});
}
bool FRiderLinkModule::FireAsyncAction(TFunction<void(JetBrains::EditorPlugin::RdEditorModel const&)> Handler)
{
FRWScopeLock Lock(ModelLock, SLT_ReadOnly);
if(!RdIsModelAlive.has_value()) return false;
if(RdIsModelAlive.get())
{
Handler(*EditorModel.Get());
}
return RdIsModelAlive.get();
}
#undef LOCTEXT_NAMESPACE