1#ifndef SEAD_TASKMGR_H_
2#define SEAD_TASKMGR_H_
3
4#include <framework/seadHeapPolicies.h>
5#include <framework/seadMethodTree.h>
6#include <framework/seadTaskBase.h>
7#include <heap/seadHeapMgr.h>
8#include <thread/seadCriticalSection.h>
9
10namespace sead
11{
12class DelegateThread;
13class Framework;
14class Heap;
15class NullFaderTask;
16
17class TaskMgr
18{
19public:
20 struct InitializeArg
21 {
22 public:
23 InitializeArg(const TaskBase::CreateArg& roottask_arg)
24 : create_queue_size(0x20), prepare_stack_size(0x8000), prepare_priority(-1),
25 roottask_create_arg(roottask_arg), heap(NULL), parent_framework(NULL)
26 {
27 }
28
29 u32 create_queue_size;
30 u32 prepare_stack_size;
31 s32 prepare_priority;
32 const TaskBase::CreateArg& roottask_create_arg;
33 Heap* heap;
34 Framework* parent_framework;
35 };
36
37 class TaskCreateContextMgr;
38
39public:
40 TaskMgr(const InitializeArg& arg);
41
42 void appendToList_(TaskBase::List& ls, TaskBase* task);
43 bool changeTaskState_(TaskBase* task, TaskBase::State state);
44 void destroyTaskSync(TaskBase* task);
45 void doDestroyTask_(TaskBase* task);
46 void finalize();
47
48 void beforeCalc();
49 void afterCalc();
50
51 CriticalSection mCriticalSection;
52 Framework* mParentFramework;
53 DelegateThread* mPrepareThread;
54 NullFaderTask* mNullFaderTask;
55 TaskBase::List mPrepareList;
56 TaskBase::List mPrepareDoneList;
57 TaskBase::List mActiveList;
58 TaskBase::List mStaticList;
59 TaskBase::List mDyingList;
60 TaskBase::List mDestroyableList;
61 HeapArray mHeapArray;
62 TaskCreateContextMgr* mTaskCreateContextMgr;
63 u32 mMaxCreateQueueSize;
64 TaskBase* mRootTask;
65 TaskBase::CreateArg mRootTaskCreateArg;
66 TaskMgr::InitializeArg mInitializeArg;
67 MethodTreeNode mCalcDestructionTreeNode;
68 u32 useless1;
69 u32 useless2;
70};
71
72} // namespace sead
73
74#define SEAD_TASK_SINGLETON(CLASS) \
75public: \
76 class SingletonDisposer_ \
77 { \
78 public: \
79 ~SingletonDisposer_() \
80 { \
81 if (mActive) \
82 CLASS::sInstance = nullptr; \
83 } \
84 \
85 bool mActive = false; \
86 }; \
87 \
88 static CLASS* instance() { return sInstance; } \
89 static void setInstance_(sead::TaskBase* task); \
90 static void deleteInstance(); \
91 \
92 CLASS(const CLASS&) = delete; \
93 CLASS& operator=(const CLASS&) = delete; \
94 CLASS(CLASS&&) = delete; \
95 CLASS& operator=(CLASS&&) = delete; \
96 \
97protected: \
98 static CLASS* sInstance; \
99 \
100 friend class SingletonDisposer_; \
101 SingletonDisposer_ mSingletonDisposer;
102
103#define SEAD_TASK_SINGLETON_IMPL(CLASS) \
104 void CLASS::setInstance_(sead::TaskBase* task) \
105 { \
106 if (!sInstance) \
107 { \
108 sInstance = static_cast<CLASS*>(task); \
109 sInstance->mSingletonDisposer.mActive = true; \
110 } \
111 else \
112 { \
113 SEAD_ASSERT_MSG(false, "Create Singleton Twice (%s) : addr %p", #CLASS, sInstance); \
114 } \
115 } \
116 \
117 void CLASS::deleteInstance() \
118 { \
119 if (sInstance) \
120 { \
121 sInstance->mTaskMgr->destroyTaskSync(sInstance); \
122 sInstance = nullptr; \
123 } \
124 } \
125 \
126 CLASS* CLASS::sInstance = nullptr;
127
128#endif // SEAD_TASKMGR_H_
129