#pragma once #define SEND_THREAD_MESSAGE(Target, Message) Target::Get().ReceiveMessage(Message) class ISingleton; class FThreadMessage { public: virtual ~FThreadMessage() {} virtual void Do() = 0; virtual ISingleton* GetTarget() { return nullptr; } virtual FName GetName() { return NAME_None; } }; #define THREAD_MESSAGE_PARAM() #define DECLARE_THREAD_MESSAGE(Target, ClassName, Param) \ class FThreadMessage_##ClassName : public FThreadMessage \ { \ public: \ virtual ISingleton* GetTarget() override { return &Target::Get(); } \ virtual FName GetName() override { return #ClassName; } \ struct FArgs{ \ Param \ };\ void PushToThread() { GetTarget()->PushMessage(this); } \ FThreadMessage_##ClassName(FArgs InArgs) : Args(InArgs) {} \ public: \ virtual void Do() override { Private_Do(); } \ private: \ void Private_Do(); \ FArgs Args; \ }; \ void FThreadMessage_##ClassName::Private_Do() #define DECLARE_PROMISE_THREAD_MESSAGE(Target, ClassName, Return, Param) \ class FThreadMessage_##ClassName : public FThreadMessage \ { \ TPromise Promise; \ public: \ virtual ISingleton* GetTarget() override { return &Target::Get(); } \ virtual FName GetName() override { return #ClassName; } \ struct FArgs{ \ Param \ };\ void Done(Return Result) { Promise.SetValue(Result); } \ TFuture PushToThread() { GetTarget()->PushMessage(this); return Promise.GetFuture(); }\ FThreadMessage_##ClassName(FArgs InArgs) : Args(InArgs) { Promise = TPromise(); } \ public: \ virtual void Do() override { Private_Do(); } \ private: \ void Private_Do(); \ FArgs Args; \ }; \ void FThreadMessage_##ClassName::Private_Do() #define FRIEND_THREAD_MESSAGE(ClassName) friend class FThreadMessage_##ClassName;