// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Object.h"
#include "Engine/Core/Types/String.h"
#include "Engine/Core/NonCopyable.h"
#include "Engine/Core/Delegate.h"
class IRunnable;
///
/// Base class for thread objects.
///
/// Ensure to call Kill or Join before deleting thread object.
class FLAXENGINE_API ThreadBase : public Object, public NonCopyable
{
public:
///
/// The custom event called before thread execution just after startup. Can be used to setup per-thread state or data. Argument is: thread handle.
///
static Delegate ThreadStarting;
///
/// The custom event called after thread execution just before exit. Can be used to cleanup per-thread state or data. Arguments are: thread handle and exit code.
///
static Delegate ThreadExiting;
protected:
IRunnable* _runnable;
#if BUILD_DEBUG
String _runnableName;
#endif
ThreadPriority _priority;
String _name;
uint64 _id;
bool _isRunning;
bool _callAfterWork;
ThreadBase(IRunnable* runnable, const String& name, ThreadPriority priority);
public:
///
/// Gets priority level of the thread.
///
FORCE_INLINE ThreadPriority GetPriority() const
{
return _priority;
}
///
/// Sets priority level of the thread
///
/// The thread priority to change to.
void SetPriority(ThreadPriority priority);
///
/// Gets thread ID
///
FORCE_INLINE uint64 GetID() const
{
return _id;
}
///
/// Gets thread running state.
///
FORCE_INLINE bool IsRunning() const
{
return _isRunning;
}
///
/// Gets name of the thread.
///
FORCE_INLINE const String& GetName() const
{
return _name;
}
public:
///
/// Aborts the thread execution by force.
///
/// True if should wait for thread end, otherwise false.
void Kill(bool waitForJoin = false);
///
/// Stops the current thread execution and waits for the thread execution end.
///
virtual void Join() = 0;
protected:
int32 Run();
virtual void ClearHandleInternal() = 0;
virtual void SetPriorityInternal(ThreadPriority priority) = 0;
virtual void KillInternal(bool waitForJoin) = 0;
public:
// [Object]
String ToString() const override
{
return _name;
}
};