// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved. #pragma once #include "Task.h" #include "Engine/Core/Types/String.h" // Invokes a target method on a main thread (using task or directly if already on main thread) // Example: INVOKE_ON_MAIN_THREAD(Collector, Collector::SyncData, this); #define INVOKE_ON_MAIN_THREAD(targetType, targetMethod, targetObject) \ if (IsInMainThread()) \ { \ targetObject->targetMethod(); \ } else { \ Function action; \ action.Bind(targetObject); \ Task::StartNew(New(action))->Wait(); \ } /// /// General purpose task executed on Main Thread in the beginning of the next frame. /// /// class FLAXENGINE_API MainThreadTask : public Task { friend class Engine; protected: /// /// Initializes a new instance of the class. /// MainThreadTask() : Task() { } private: /// /// Runs all main thread tasks. Called only by the Engine class. /// static void RunAll(); public: // [Task] String ToString() const override { return String::Format(TEXT("Main Thread Task ({0})"), ::ToString(GetState())); } bool HasReference(Object* obj) const override { return false; } protected: // [Task] void Enqueue() override; }; /// /// General purpose task executing custom action using Main Thread in the beginning of the next frame. /// /// /// class FLAXENGINE_API MainThreadActionTask : public MainThreadTask { protected: Function _action1; Function _action2; Object* _target; public: /// /// Initializes a new instance of the class. /// /// The action. /// The target object. MainThreadActionTask(Function& action, Object* target = nullptr) : MainThreadTask() , _action1(action) , _target(target) { } /// /// Initializes a new instance of the class. /// /// The action. /// The target object. MainThreadActionTask(Function::Signature action, Object* target = nullptr) : MainThreadTask() , _action1(action) , _target(target) { } /// /// Initializes a new instance of the class. /// /// The action. /// The target object. MainThreadActionTask(Function& action, Object* target = nullptr) : MainThreadTask() , _action2(action) , _target(target) { } /// /// Initializes a new instance of the class. /// /// The action. /// The target object. MainThreadActionTask(Function::Signature action, Object* target = nullptr) : MainThreadTask() , _action2(action) , _target(target) { } protected: // [MainThreadTask] bool Run() override { if (_action1.IsBinded()) { _action1(); return false; } if (_action2.IsBinded()) { return _action2(); } return true; } public: // [MainThreadTask] bool HasReference(Object* obj) const override { return obj == _target; } };