the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#pragma once
2#include <queue>
3
4typedef int (C4JThreadStartFunc)(void* lpThreadParameter);
5
6class Level;
7
8#if defined(_XBOX_ONE) || defined(__ORBIS__)
9
10#define CPU_CORE_MAIN_THREAD 0
11
12#define CPU_CORE_SERVER 1
13
14#define CPU_CORE_CHUNK_UPDATE 2
15#define CPU_CORE_REMOVE_PLAYER 2
16
17#define CPU_CORE_CHUNK_REBUILD_A 3
18#define CPU_CORE_SAVE_THREAD_A 3
19#define CPU_CORE_UI_SCENE 3
20#define CPU_CORE_POST_PROCESSING 3
21#define CPU_CORE_DQR_REALTIMESESSION 3
22
23#define CPU_CORE_CHUNK_REBUILD_B 4
24#define CPU_CORE_SAVE_THREAD_B 4
25#define CPU_CORE_TILE_UPDATE 4
26#define CPU_CORE_CONNECTIONS 4
27
28#define CPU_CORE_CHUNK_REBUILD_C 5
29#define CPU_CORE_SAVE_THREAD_C 5
30#define CPU_CORE_LEADERBOARDS 5 // Orbis only
31
32#else
33
34#define CPU_CORE_MAIN_THREAD 0
35
36#define CPU_CORE_CHUNK_REBUILD_A 1
37#define CPU_CORE_SAVE_THREAD_A 1
38#define CPU_CORE_TILE_UPDATE 1
39#define CPU_CORE_CONNECTIONS 1
40
41#define CPU_CORE_CHUNK_UPDATE 2
42#define CPU_CORE_REMOVE_PLAYER 2
43
44#define CPU_CORE_CHUNK_REBUILD_B 3
45#define CPU_CORE_SAVE_THREAD_B 3
46#define CPU_CORE_UI_SCENE 3
47#define CPU_CORE_POST_PROCESSING 3
48
49#define CPU_CORE_SERVER 4
50
51#define CPU_CORE_CHUNK_REBUILD_C 5
52#define CPU_CORE_SAVE_THREAD_C 5
53#define CPU_CORE_LEADERBOARDS 5 // Sony only
54
55#endif
56
57class C4JThread
58{
59public:
60
61 class Event
62 {
63 public:
64 enum EMode
65 {
66 e_modeAutoClear,
67 e_modeManualClear
68 };
69 Event(EMode mode = e_modeAutoClear);
70 ~Event();
71 void Set();
72 void Clear();
73 DWORD WaitForSignal(int timeoutMs);
74
75 private:
76 EMode m_mode;
77 #ifdef __PS3__
78 sys_event_flag_t m_event;
79 #elif defined __ORBIS__
80 SceKernelEventFlag m_event;
81 #elif defined __PSVITA__
82 SceUID m_event;
83 #else
84 HANDLE m_event;
85 #endif // __PS3__
86 };
87
88 class EventArray
89 {
90 public:
91 enum EMode
92 {
93 e_modeAutoClear,
94 e_modeManualClear
95 };
96
97 EventArray(int size, EMode mode = e_modeAutoClear);
98
99 void Set(int index);
100 void Clear(int index);
101 void SetAll();
102 void ClearAll();
103 DWORD WaitForAll(int timeoutMs);
104 DWORD WaitForAny(int timeoutMs);
105 DWORD WaitForSingle(int index, int timeoutMs);
106#ifdef __PS3__
107 void Cancel();
108#endif
109
110 private:
111 int m_size;
112 EMode m_mode;
113#ifdef __PS3__
114 sys_event_flag_t m_events;
115#elif defined __ORBIS__
116 SceKernelEventFlag m_events;
117#elif defined __PSVITA__
118 SceUID m_events;
119#else
120 HANDLE* m_events;
121#endif // __PS3__
122 };
123
124
125
126 class EventQueue
127 {
128 typedef void (UpdateFunc)(void* lpParameter);
129 typedef void (ThreadInitFunc)();
130
131 C4JThread* m_thread;
132 std::queue<void*> m_queue;
133 C4JThread::EventArray* m_startEvent;
134 C4JThread::Event* m_finishedEvent;
135 CRITICAL_SECTION m_critSect;
136 UpdateFunc* m_updateFunc;
137 ThreadInitFunc* m_threadInitFunc;
138 char m_threadName[64];
139 int m_processor;
140 int m_priority;
141 void init();
142 static int threadFunc(void* lpParam);
143 void threadPoll();
144
145 public:
146 EventQueue(UpdateFunc* updateFunc, ThreadInitFunc threadInitFunc, const char* szThreadName);
147 void setProcessor(int proc) { m_processor = proc; if(m_thread) m_thread->SetProcessor(proc); }
148 void setPriority(int priority) { m_priority = priority; if(m_thread) m_thread->SetPriority(priority); }
149 void sendEvent(Level* pLevel);
150 void waitForFinish();
151 };
152
153
154
155 C4JThread(C4JThreadStartFunc* startFunc, void* param, const char* threadName, int stackSize = 0);
156 C4JThread( const char* mainThreadName ); // only used for the main thread
157 ~C4JThread();
158
159 void Run();
160 bool isRunning() { return m_isRunning; }
161 bool hasStarted() { return m_hasStarted; }
162 void SetProcessor(int proc);
163 void SetPriority(int priority);
164 DWORD WaitForCompletion(int timeoutMs);
165 int GetExitCode();
166 char* getName() { return m_threadName; }
167 static void Sleep(int millisecs);
168 static C4JThread* getCurrentThread();
169 static bool isMainThread();
170 static char* getCurrentThreadName() { return getCurrentThread()->getName(); }
171
172#ifdef __ORBIS__
173 static void PushAffinityAllCores(); // PS4 only
174 static void PopAffinity();
175 static __thread SceKernelCpumask m_oldAffinityMask;
176#endif // __ORBIS__
177
178#ifdef _XBOX_ONE
179 static void StaticInit();
180#endif
181
182private:
183 void* m_threadParam;
184 C4JThreadStartFunc* m_startFunc;
185 int m_stackSize;
186 char m_threadName[64];
187 bool m_isRunning;
188 bool m_hasStarted;
189 int m_exitCode;
190 __int64 m_lastSleepTime;
191 static std::vector<C4JThread*> ms_threadList;
192 static CRITICAL_SECTION ms_threadListCS;
193
194#ifdef _XBOX_ONE
195 // 4J Stu - On XboxOne the main thread is not the one that does all the static init, so we have to set this up later
196 static C4JThread *m_mainThread;
197#else
198 static C4JThread m_mainThread;
199#endif
200
201#ifdef __PS3__
202 sys_ppu_thread_t m_threadID;
203 Event *m_completionFlag;
204 int m_priority;
205 static void entryPoint(uint64_t);
206#elif defined __ORBIS__
207 ScePthreadAttr m_threadAttr;
208 ScePthread m_threadID;
209 Event *m_completionFlag;
210 int m_priority;
211 static void *entryPoint(void *);
212#elif defined __PSVITA__
213 SceUID m_threadID;
214 Event *m_completionFlag;
215 int m_priority;
216 static SceInt32 entryPoint(SceSize argSize, void *pArgBlock);
217#else
218 DWORD m_threadID;
219 HANDLE m_threadHandle;
220 Event *m_completionFlag;
221 static DWORD WINAPI entryPoint(LPVOID lpParam);
222#endif
223};
224void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName );
225
226
227class CriticalSectionScopeLock
228{
229 CRITICAL_SECTION* m_pCS;
230public:
231 CriticalSectionScopeLock(CRITICAL_SECTION* pCS) { m_pCS = pCS; EnterCriticalSection(m_pCS); }
232 ~CriticalSectionScopeLock() { LeaveCriticalSection(m_pCS); }
233};
234