diff options
author | chai <chaifix@163.com> | 2021-10-25 23:29:21 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-10-25 23:29:21 +0800 |
commit | 7ecf913256fb396e3027aac3318d996a716a52ef (patch) | |
tree | 4540835c881a63b665e2a692bf30115fd29e8bb0 /Runtime | |
parent | 0816cd70ca1a213b6ed872bcf3c0bf0912473722 (diff) |
+ job system
Diffstat (limited to 'Runtime')
29 files changed, 709 insertions, 68 deletions
diff --git a/Runtime/Threads/Mutex.cpp b/Runtime/Common/DataBuffer.cpp index e69de29..e69de29 100644 --- a/Runtime/Threads/Mutex.cpp +++ b/Runtime/Common/DataBuffer.cpp diff --git a/Runtime/Common/DataBuffer.h b/Runtime/Common/DataBuffer.h new file mode 100644 index 0000000..330128f --- /dev/null +++ b/Runtime/Common/DataBuffer.h @@ -0,0 +1,14 @@ +#pragma once +#include "Runtime/Lua/LuaHelper.h" + +// 描述内存对象,会作为 +// 1. 多线程读取文件的返回 +class DataBuffer : public LuaBind::NativeClass<DataBuffer> +{ +public: + DataBuffer(LuaBind::VM* vm); + ~DataBuffer(); + + char* data; + int length; +};
\ No newline at end of file diff --git a/Runtime/Debug/Log.cpp b/Runtime/Debug/Log.cpp index cc5b2e3..a84337b 100644 --- a/Runtime/Debug/Log.cpp +++ b/Runtime/Debug/Log.cpp @@ -1,3 +1,4 @@ +#include "Runtime/Threading/Mutex.h" #include "log.h" #include <iostream> #include <ctime> @@ -12,6 +13,8 @@ static HANDLE s_ConsoleHandle = 0; unordered_set<string> s_OpenTags; +Mutex s_Mutex; + #ifdef GAMELAB_DEBUG // https://stackoverflow.com/questions/997946/how-to-get-current-time-and-date-in-c // Get current date/time, format is YYYY-MM-DD.HH:mm:ss @@ -39,41 +42,47 @@ void log_open_tag(std::string tag) void log_info(std::string log) { + _lock(s_Mutex) { #ifdef GAMELAB_WIN - if (s_ConsoleHandle == 0) { - s_ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); - } - SetConsoleTextAttribute(s_ConsoleHandle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); - cout << currentDateTime() << " [Info] " << log << endl; + if (s_ConsoleHandle == 0) { + s_ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); + } + SetConsoleTextAttribute(s_ConsoleHandle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); + cout << currentDateTime() << " [Info] " << log << endl; #else - cout << "\x1B[97m" << currentDateTime() << " [Info] " << log << "\x1B[0m" << endl; + cout << "\x1B[97m" << currentDateTime() << " [Info] " << log << "\x1B[0m" << endl; #endif + } } void log_warning(std::string log) { + _lock(s_Mutex) { #ifdef GAMELAB_WIN - if (s_ConsoleHandle == 0) { - s_ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); - } - SetConsoleTextAttribute(s_ConsoleHandle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY); - cout << currentDateTime() << " [Info] " << log << endl; + if (s_ConsoleHandle == 0) { + s_ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); + } + SetConsoleTextAttribute(s_ConsoleHandle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY); + cout << currentDateTime() << " [Info] " << log << endl; #else - cout << "\x1B[93m" << currentDateTime() << " [Info] " << log << "\x1B[0m" << endl; + cout << "\x1B[93m" << currentDateTime() << " [Info] " << log << "\x1B[0m" << endl; #endif + } } void log_error(std::string log) { + _lock(s_Mutex) { #ifdef GAMELAB_WIN - if (s_ConsoleHandle == 0) { - s_ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); - } - SetConsoleTextAttribute(s_ConsoleHandle, FOREGROUND_RED | FOREGROUND_INTENSITY); - cout << currentDateTime() << " [Info] " << log << endl; + if (s_ConsoleHandle == 0) { + s_ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); + } + SetConsoleTextAttribute(s_ConsoleHandle, FOREGROUND_RED | FOREGROUND_INTENSITY); + cout << currentDateTime() << " [Info] " << log << endl; #else - cout << "\x1B[91m" << currentDateTime() << " [Info] " << log << "\x1B[0m" << endl; + cout << "\x1B[91m" << currentDateTime() << " [Info] " << log << "\x1B[0m" << endl; #endif + } } void log_error_null_param(std::string funcName, std::string param) diff --git a/Runtime/Threads/Mutex.h b/Runtime/FileSystem/File.cpp index e69de29..e69de29 100644 --- a/Runtime/Threads/Mutex.h +++ b/Runtime/FileSystem/File.cpp diff --git a/Runtime/FileSystem/File.h b/Runtime/FileSystem/File.h new file mode 100644 index 0000000..19e780d --- /dev/null +++ b/Runtime/FileSystem/File.h @@ -0,0 +1,9 @@ +#pragma once +#include "Runtime/Lua/LuaHelper.h" + +class File +{ +public: + + +}; diff --git a/Runtime/FileSystem/FileJobs.cpp b/Runtime/FileSystem/FileJobs.cpp new file mode 100644 index 0000000..29e99a4 --- /dev/null +++ b/Runtime/FileSystem/FileJobs.cpp @@ -0,0 +1,27 @@ +#include <fstream> +#include "FileJobs.h" + +using namespace std; + +void ReadFilesJob::Dispacth(void* param) +{ + LUA_BIND_STATE((lua_State*)param); + if (!callback) + return; + callback.PushRef(state); + state.Call(0, 0); +} + +void ReadFilesJob::Process() +{ + if (IsFinished()) + return; + ifstream infile; + infile.open(files[cur]); + ++cur; +} + +bool ReadFilesJob::IsFinished() +{ + return cur >= files.size(); +}
\ No newline at end of file diff --git a/Runtime/FileSystem/FileJobs.h b/Runtime/FileSystem/FileJobs.h new file mode 100644 index 0000000..2e53a39 --- /dev/null +++ b/Runtime/FileSystem/FileJobs.h @@ -0,0 +1,22 @@ +#pragma once + +#include <vector> +#include "Runtime/Threading/Job.h" +#include "Runtime/Lua/LuaHelper.h" +#include "Runtime/Threading/JobSystem.h" + +class ReadFilesJob : public Job +{ +public: + ReadFilesJob(LuaBind::VM* vm) : callback(vm), cur(0) {} + ~ReadFilesJob() {} + + void Dispacth(void* param) override; + void Process() override; + bool IsFinished() override; + + int cur = 0; //当前处理的文件 + std::vector<std::string> files; // 文件路径 + LuaBind::StrongRef callback; // 完成后的回调函数 + +}; diff --git a/Runtime/FileSystem/FileSystem.cpp b/Runtime/FileSystem/FileSystem.cpp deleted file mode 100644 index 8816f78..0000000 --- a/Runtime/FileSystem/FileSystem.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "FileSystem.h" - -FileSystem& GetFileSystem() { - if (!FileSystem::m_Instance) - { - FileSystem::m_Instance = new FileSystem(); - } - return *FileSystem::m_Instance; -} diff --git a/Runtime/FileSystem/FileSystem.h b/Runtime/FileSystem/FileSystem.h deleted file mode 100644 index aae39c1..0000000 --- a/Runtime/FileSystem/FileSystem.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef FILESYSTEM_H -#define FILESYSTEM_H - -#include <string> - -class FileSystem -{ -public: - std::string GetDataPath(); - std::string GetPersistentPath(); - std::string GetTempPath(); - -private: - FileSystem(); - - static FileSystem* m_Instance; - - friend FileSystem& GetFileSystem(); - -}; - -FileSystem& GetFileSystem(); - -#endif
\ No newline at end of file diff --git a/Runtime/FileSystem/Unzip.h b/Runtime/FileSystem/Unzip.h index e69de29..45dcbb0 100644 --- a/Runtime/FileSystem/Unzip.h +++ b/Runtime/FileSystem/Unzip.h @@ -0,0 +1,3 @@ +#pragma once + + diff --git a/Runtime/Graphics/ImageData.h b/Runtime/Graphics/ImageData.h index a3162bc..af44f11 100644 --- a/Runtime/Graphics/ImageData.h +++ b/Runtime/Graphics/ImageData.h @@ -2,14 +2,15 @@ #define IMAGE_DATA_H #include <vector> +#include "Runtime/Threading/Job.h" // 图片像素数据 class ImageData { -public: +public: enum ImageFormat { - ImageFormat_Rgba_Int, + ImageFormat_Rgba_Int, ImageFormat_Rgba_Float, }; @@ -30,7 +31,7 @@ struct ImageDataRequest bool isDone, hasError; int error; int progress, all; - ImageData* result; + ImageData* result; std::vector<ImageData*> results; }; @@ -41,4 +42,14 @@ namespace ImageDataUtil ImageDataRequest* LoadAsync(std::vector<const char*> paths); } +class ReadImageFilesJob : public Job +{ + +}; + +class DecodeImageFilesJob : public Job +{ + +}; + #endif
\ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindClass.hpp b/Runtime/Lua/LuaBind/LuaBindClass.hpp index eb028c2..7fb4529 100644 --- a/Runtime/Lua/LuaBind/LuaBindClass.hpp +++ b/Runtime/Lua/LuaBind/LuaBindClass.hpp @@ -414,7 +414,7 @@ namespace LuaBind PushMemberRef(state, script); state.GetField(-1, method); PushMemberRef(state, script); - state.Call(1, 0); + state.Call(1, 0, onErrorOccured); state.SetTop(top); } @@ -512,7 +512,7 @@ namespace LuaBind if (state.IsType(-1, LUA_TFUNCTION)) { lua_pushvalue(L, 1); // userdata - state.Call(1, 1); // 派生类的GetClassName函数 + state.Call(1, 1, onErrorOccured); // 派生类的GetClassName函数 classname = state.GetValue<cc8*>(-1, ""); } else diff --git a/Runtime/Lua/LuaBind/LuaBindState.cpp b/Runtime/Lua/LuaBind/LuaBindState.cpp index 7c5f043..137acbf 100644 --- a/Runtime/Lua/LuaBind/LuaBindState.cpp +++ b/Runtime/Lua/LuaBind/LuaBindState.cpp @@ -8,7 +8,8 @@ namespace LuaBind { - OnRegisterClassHandler onRegisterNativeClass; + OnRegisterClassHandler onRegisterNativeClass = NULL; + ErrorHandler onErrorOccured = NULL; std::string g_NameSpace = ""; @@ -114,6 +115,10 @@ namespace LuaBind { //luaL_dofile(mState, path.c_str()); LoadFile(path); + if (handler == NULL) + { + handler = onErrorOccured; + } Call(0, 0, handler); } @@ -161,6 +166,10 @@ namespace LuaBind void State::Call(int nArgs, int nResults, ErrorHandler handler) { + if (handler == NULL) + { + handler = onErrorOccured; + } int oldTop = GetTop() - nArgs - 1; int func = 0; if (handler != NULL) diff --git a/Runtime/Lua/LuaBind/LuaBindState.h b/Runtime/Lua/LuaBind/LuaBindState.h index e7e2807..071287f 100644 --- a/Runtime/Lua/LuaBind/LuaBindState.h +++ b/Runtime/Lua/LuaBind/LuaBindState.h @@ -17,6 +17,7 @@ namespace LuaBind typedef void (*ErrorHandler) (cc8 * msg); typedef void(*OnRegisterClassHandler)(State&, int clsIdx, std::string clsName, std::string pkgName); + extern ErrorHandler onErrorOccured; extern OnRegisterClassHandler onRegisterNativeClass; extern std::string g_NameSpace; diff --git a/Runtime/Scripting/FileSystem/FileSystem.bind.cpp b/Runtime/Scripting/FileSystem/FileSystem.bind.cpp deleted file mode 100644 index fea8b57..0000000 --- a/Runtime/Scripting/FileSystem/FileSystem.bind.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include <iostream>
-
-#include "Runtime/Lua/LuaBind/LuaBind.h"
-
-int luaopen_GameLab_FileSystem(lua_State* L)
-{
-
- return 1;
-}
-
diff --git a/Runtime/Scripting/GL/GL.bind.cpp b/Runtime/Scripting/GL/GL.bind.cpp index f167237..f4c9f50 100644 --- a/Runtime/Scripting/GL/GL.bind.cpp +++ b/Runtime/Scripting/GL/GL.bind.cpp @@ -212,11 +212,187 @@ int MatrixMode(lua_State* L) return 0; } -// GL.LoadMatrix([Matrix4x4, mat44ColumnMajorTable]) +// GL.LoadMatrix([Matrix44, mat44ColumnMajorTable]) int LoadMatrix(lua_State* L) { LUA_BIND_STATE(L); + if (LuaHelper::IsType(state, "GameLab.Engine.Math.Matrix44", 1)) + { + float m[16]; + m[0] = state.GetField(1, "m00", 0.f); + m[1] = state.GetField(1, "m10", 0.f); + m[2] = state.GetField(1, "m20", 0.f); + m[3] = state.GetField(1, "m30", 0.f); + + m[4] = state.GetField(1, "m01", 0.f); + m[5] = state.GetField(1, "m11", 0.f); + m[6] = state.GetField(1, "m21", 0.f); + m[7] = state.GetField(1, "m31", 0.f); + + m[8] = state.GetField(1, "m02", 0.f); + m[9] = state.GetField(1, "m12", 0.f); + m[10] = state.GetField(1, "m22", 0.f); + m[11] = state.GetField(1, "m32", 0.f); + + m[12] = state.GetField(1, "m03", 0.f); + m[13] = state.GetField(1, "m13", 0.f); + m[14] = state.GetField(1, "m23", 0.f); + m[15] = state.GetField(1, "m33", 0.f); + + glLoadMatrixf(m); + } + else if (LuaHelper::IsType(state, "table", 1)) + { + float m[16]; + m[0] = state.GetField(1, 1, 0.f); + m[1] = state.GetField(1, 2, 0.f); + m[2] = state.GetField(1, 3, 0.f); + m[3] = state.GetField(1, 4, 0.f); + + m[4] = state.GetField(1, 5, 0.f); + m[5] = state.GetField(1, 6, 0.f); + m[6] = state.GetField(1, 7, 0.f); + m[7] = state.GetField(1, 8, 0.f); + + m[8] = state.GetField(1, 9, 0.f); + m[9] = state.GetField(1, 10, 0.f); + m[10] = state.GetField(1, 11, 0.f); + m[11] = state.GetField(1, 12, 0.f); + + m[12] = state.GetField(1, 13, 0.f); + m[13] = state.GetField(1, 14, 0.f); + m[14] = state.GetField(1, 15, 0.f); + m[15] = state.GetField(1, 16, 0.f); + + glLoadMatrixf(m); + } + else + { + state.ErrorType(1, "Matrix44 or mat44ColumnMajorTable"); + } + + return 0; +} + +// GL.Ortho(l,r,b,t,n,f) +int OrthoMatrix(lua_State* L) +{ + LUA_BIND_STATE(L); + double l = state.GetValue<double>(1, 0); + double r = state.GetValue<double>(2, 0); + double b = state.GetValue<double>(3, 0); + double t = state.GetValue<double>(4, 0); + double n = state.GetValue<double>(5, 0); + double f = state.GetValue<double>(6, 0); + glOrtho(l, r, b, t, n, f); + return 0; +} + +// GL.Ortho(l,r,b,t,n,f) +int FrustumMatrix(lua_State* L) +{ + LUA_BIND_STATE(L); + double l = state.GetValue<double>(1, 0); + double r = state.GetValue<double>(2, 0); + double b = state.GetValue<double>(3, 0); + double t = state.GetValue<double>(4, 0); + double n = state.GetValue<double>(5, 0); + double f = state.GetValue<double>(6, 0); + glFrustum(l, r, b, t, n, f); + return 0; +} + +int MultMatrix(lua_State* L) +{ + LUA_BIND_STATE(L); + + if (LuaHelper::IsType(state, "GameLab.Engine.Math.Matrix44", 1)) + { + float m[16]; + m[0] = state.GetField(1, "m00", 0); + m[1] = state.GetField(1, "m10", 0); + m[2] = state.GetField(1, "m20", 0); + m[3] = state.GetField(1, "m30", 0); + + m[4] = state.GetField(1, "m01", 0); + m[5] = state.GetField(1, "m11", 0); + m[6] = state.GetField(1, "m21", 0); + m[7] = state.GetField(1, "m31", 0); + + m[8] = state.GetField(1, "m02", 0); + m[9] = state.GetField(1, "m12", 0); + m[10] = state.GetField(1, "m22", 0); + m[11] = state.GetField(1, "m32", 0); + + m[12] = state.GetField(1, "m03", 0); + m[13] = state.GetField(1, "m13", 0); + m[14] = state.GetField(1, "m23", 0); + m[15] = state.GetField(1, "m33", 0); + + glMultMatrixf(m); + } + else if (LuaHelper::IsType(state, "table", 1)) + { + float m[16]; + m[0] = state.GetField(1, 1, 0); + m[1] = state.GetField(1, 2, 0); + m[2] = state.GetField(1, 3, 0); + m[3] = state.GetField(1, 4, 0); + + m[4] = state.GetField(1, 5, 0); + m[5] = state.GetField(1, 6, 0); + m[6] = state.GetField(1, 7, 0); + m[7] = state.GetField(1, 8, 0); + + m[8] = state.GetField(1, 9, 0); + m[9] = state.GetField(1, 10, 0); + m[10] = state.GetField(1, 11, 0); + m[11] = state.GetField(1, 12, 0); + + m[12] = state.GetField(1, 13, 0); + m[13] = state.GetField(1, 14, 0); + m[14] = state.GetField(1, 15, 0); + m[15] = state.GetField(1, 16, 0); + + glMultMatrixf(m); + } + else + { + state.ErrorType(1, "Matrix44 or mat44ColumnMajorTable"); + } + + return 0; +} + +int Scale(lua_State* L) +{ + LUA_BIND_STATE(L); + float x = state.GetValue(1, 1); + float y = state.GetValue(2, 1); + float z = state.GetValue(3, 1); + glScalef(x, y, z); + return 0; +} + +int Rotate(lua_State* L) +{ + LUA_BIND_STATE(L); + float angle = state.GetValue(1, 0); + float x = state.GetValue(2, 0); + float y = state.GetValue(3, 0); + float z = state.GetValue(4, 1); + glRotatef(angle, x, y, z); + return 0; +} + +int Translate(lua_State* L) +{ + LUA_BIND_STATE(L); + float x = state.GetValue(1, 0); + float y = state.GetValue(2, 0); + float z = state.GetValue(3, 0); + glTranslatef(x, y, z); return 0; } @@ -233,6 +409,12 @@ static luaL_Reg glFuncs[] = { {"PopMatrix", PopMatrix}, {"MatrixMode", MatrixMode}, {"LoadMatrix", LoadMatrix}, + {"LoadOrthoMatrix", OrthoMatrix}, + {"LoadFrustumMatrix", FrustumMatrix}, + {"MultMatrix", MultMatrix}, + {"Scale", Scale}, + {"Rotate", Rotate}, + {"Translate", Translate}, {0, 0} }; diff --git a/Runtime/Scripting/IO/IO.bind.cpp b/Runtime/Scripting/IO/IO.bind.cpp new file mode 100644 index 0000000..d58d86f --- /dev/null +++ b/Runtime/Scripting/IO/IO.bind.cpp @@ -0,0 +1,51 @@ +#include "Runtime/Lua/LuaHelper.h" +#include "Runtime/Debug/Log.h" +#include "Runtime/FileSystem/FileJobs.h" + +// IO.ReadFiles({}, callback) +int ReadFiles(lua_State* L) +{ + LUA_BIND_STATE(L); + LUA_BIND_CHECK(L, "TF"); + + std::vector<std::string> files; + for (int i = 1; true; ++i) + { + state.GetField(1, i); + if (lua_type(L, -1) != LUA_TSTRING) + { + lua_pop(L, 1); + break; + } + const char* f = lua_tostring(L, -1); + state.Pop(1); + files.push_back(f); + } + + ReadFilesJob* job = new ReadFilesJob(state.GetVM()); + job->files = files; + job->callback.SetRef(state, 2); + + JobSystem::Instance()->AddJobAtEnd(job); + return 0; +} + +static luaL_Reg ioFuncs[] = { + {"ReadFiles", ReadFiles}, + {0, 0} +}; + +int luaopen_GameLab_IO(lua_State* L) +{ + log_info("Scripting", "luaopen_GameLab_IO()"); + + LUA_BIND_STATE(L); + + state.PushGlobalNamespace(); + state.PushNamespace("GameLab"); + state.PushNamespace("IO"); + + state.RegisterMethods(ioFuncs); + + return 1; +}
\ No newline at end of file diff --git a/Runtime/Threading/Job.cpp b/Runtime/Threading/Job.cpp new file mode 100644 index 0000000..18794c5 --- /dev/null +++ b/Runtime/Threading/Job.cpp @@ -0,0 +1,13 @@ +#include "Job.h" +#include "Runtime/Utilities/UIDGenerator.h" + +static UIDGenerator s_JobIDGenerator; + +Job::Job() + : m_ID(s_JobIDGenerator.GenUID()) +{ +} + +Job::~Job() +{ +} diff --git a/Runtime/Threading/Job.h b/Runtime/Threading/Job.h new file mode 100644 index 0000000..db89feb --- /dev/null +++ b/Runtime/Threading/Job.h @@ -0,0 +1,17 @@ +#pragma once + +// 任务的抽象基类 +class Job +{ +public: + Job(); + virtual ~Job(); + + virtual void Process() = 0; + virtual bool IsFinished() = 0; + virtual void Dispacth(void* param) = 0; // call in main thread + +protected: + int m_ID; // Job ID + +};
\ No newline at end of file diff --git a/Runtime/Threading/JobSystem.cpp b/Runtime/Threading/JobSystem.cpp new file mode 100644 index 0000000..a026300 --- /dev/null +++ b/Runtime/Threading/JobSystem.cpp @@ -0,0 +1,43 @@ +#include "JobSystem.h" + +JobSystem::JobSystem() +{ + +} + +JobSystem::~JobSystem() +{ + +} + +void JobSystem::Initilize(int workThreadCount) +{ + if (workThreadCount <= 0) + return; + + for (int i = 0; i < workThreadCount; ++i) + { + WorkThread* thread = new WorkThread(); + thread->Resume(); + m_Threads.push_back(thread); + } +} + +void JobSystem::Dispatch(void* param) +{ + for (int i = 0; i < m_Threads.size(); ++i) + { + m_Threads[i]->Dispatch(param); + } +} + +void JobSystem::AddJobAtEnd(Job* job) +{ + WorkThread* thread = SelectThread(); + thread->AddJobAtEnd(job); +} + +WorkThread* JobSystem::SelectThread() +{ + return m_Threads[0]; +}
\ No newline at end of file diff --git a/Runtime/Threading/JobSystem.h b/Runtime/Threading/JobSystem.h new file mode 100644 index 0000000..c95037c --- /dev/null +++ b/Runtime/Threading/JobSystem.h @@ -0,0 +1,22 @@ +#pragma once +#include "Runtime/Utilities/Singleton.h" +#include "Runtime/Threading/Thread.h" +#include <vector> + +class JobSystem : public Singleton<JobSystem> +{ +public: + JobSystem(); + ~JobSystem(); + + void AddJobAtEnd(Job* job); + + void Initilize(int workThreadCount = 1); + void Dispatch(void* param); + +private: + WorkThread* SelectThread(); + + std::vector<WorkThread*> m_Threads; + +};
\ No newline at end of file diff --git a/Runtime/Threading/Mutex.cpp b/Runtime/Threading/Mutex.cpp new file mode 100644 index 0000000..eabe48d --- /dev/null +++ b/Runtime/Threading/Mutex.cpp @@ -0,0 +1,25 @@ +#include "Thread.h" +#include "Mutex.h" + +Mutex::Mutex() +{ + m_Handle = ::CreateMutex(NULL, FALSE, NULL); + if (!m_Handle) + throw ThreadException("Cant use win32 mutex."); +} + +Mutex::~Mutex() +{ + ::CloseHandle(m_Handle); + m_Handle = NULL; +} + +void Mutex::Lock() +{ + ::WaitForSingleObject(m_Handle, (~(uint32)0)); +} + +void Mutex::Unlock() +{ + ::ReleaseMutex(m_Handle); +}
\ No newline at end of file diff --git a/Runtime/Threading/Mutex.h b/Runtime/Threading/Mutex.h new file mode 100644 index 0000000..44f8cb9 --- /dev/null +++ b/Runtime/Threading/Mutex.h @@ -0,0 +1,39 @@ +#pragma once +#include <windows.h> + +class Mutex +{ +public: + Mutex(); + ~Mutex(); + + void Lock(); + void Unlock(); + +private: + HANDLE m_Handle; + +}; + + +class MutexLocker +{ +public: + MutexLocker(Mutex& mutex) + : m(mutex) + { + m.Lock(); + }; + ~MutexLocker() + { + m.Unlock(); + } + operator bool() { return false; }; +private: + void* operator new(size_t); + Mutex& m; +}; + +#define _lock(m) \ +if(MutexLocker lock_##m = m){} else + diff --git a/Runtime/Threads/Semaphore.cpp b/Runtime/Threading/Semaphore.cpp index e69de29..e69de29 100644 --- a/Runtime/Threads/Semaphore.cpp +++ b/Runtime/Threading/Semaphore.cpp diff --git a/Runtime/Threads/Semaphore.h b/Runtime/Threading/Semaphore.h index e69de29..e69de29 100644 --- a/Runtime/Threads/Semaphore.h +++ b/Runtime/Threading/Semaphore.h diff --git a/Runtime/Threading/Thread.cpp b/Runtime/Threading/Thread.cpp new file mode 100644 index 0000000..0a41485 --- /dev/null +++ b/Runtime/Threading/Thread.cpp @@ -0,0 +1,69 @@ +#include <string> +#include "Thread.h" +#include "Runtime/Utilities/Assert.h" + +static std::string s_ThreadErr; + +static DWORD WINAPI ThreadMain(LPVOID param) +{ + Thread* thread = (Thread*)param; + thread->Run(); + return NULL; +} + +Thread::Thread(uint32 stacksize) +{ + m_Handle = ::CreateThread( + NULL + , stacksize + , ThreadMain + , this + , CREATE_SUSPENDED + , NULL); + if (m_Handle == 0) + { + s_ThreadErr = "Create Thread Failed. ErrorCode=" + std::to_string(GetLastError()); + throw ThreadException(s_ThreadErr.c_str()); + } +} + +Thread::~Thread() +{ + CloseHandle(m_Handle); +} + +void Thread::Resume() +{ + ::ResumeThread(m_Handle); +} + +bool Thread::IsRunning() +{ + if (m_Handle) { + DWORD exitCode = 0; + // https://blog.csdn.net/yuanmeng567/article/details/19485719 + ::GetExitCodeThread(m_Handle, &exitCode); + return exitCode == STILL_ACTIVE; + } + return false; +} + +void Thread::Join() +{ + ::WaitForSingleObject(m_Handle, INFINITE); +} + +void Thread::Kill() +{ + ::TerminateThread(m_Handle, FALSE); +} + +void Thread::Sleep(uint ms) +{ + ::Sleep(ms); +} + +bool Thread::IsCurrent() +{ + return m_Handle == ::GetCurrentThread(); +} diff --git a/Runtime/Threading/Thread.h b/Runtime/Threading/Thread.h new file mode 100644 index 0000000..ea86e16 --- /dev/null +++ b/Runtime/Threading/Thread.h @@ -0,0 +1,70 @@ +#pragma once +#include <windows.h> +#include <vector> +#include <exception> + +#include "Job.h" +#include "Runtime/Utilities/Type.h" +#include "Mutex.h" + +class ThreadException : public std::exception +{ +public: + ThreadException(const char* what) + : std::exception(what) + { + } +}; + +class Thread +{ +public: + Thread(uint32 stacksize = 0)/*throw ThreadExeception*/; + virtual ~Thread(); + + virtual void Run() = 0; + + virtual void Resume(); + virtual void Join() ; + virtual void Kill() ; + + virtual void Sleep(uint ms) ; + + virtual bool IsRunning() ; + virtual bool IsCurrent() ; + +protected: + HANDLE m_Handle; + +}; + +// 任务系统的线程 +class WorkThread : public Thread +{ +public: + void Run() override; + void Dispatch(void* param); // call in main thread + + void AddJobAtEnd(Job* job); + +private: + Mutex m_PendingMutex; + Mutex m_FinishedMutex; + + std::vector<Job*> m_PendingJobs; + std::vector<Job*> m_FinishedJobs; + +}; + +// 执行小段代码的线程 +class CodePieceThread : public Thread +{ +public: + typedef void(*CodePiece)(); + + void Run() override; + +private: + std::vector<CodePiece> m_CodePieces; + +};
\ No newline at end of file diff --git a/Runtime/Threading/WorkThread.cpp b/Runtime/Threading/WorkThread.cpp new file mode 100644 index 0000000..b3b462a --- /dev/null +++ b/Runtime/Threading/WorkThread.cpp @@ -0,0 +1,48 @@ +#include "Thread.h" +#include "Runtime/Debug/Log.h" + +void WorkThread::Run() +{ + while (true) + { + _lock(m_PendingMutex) + { + for (auto iter = m_PendingJobs.begin(); iter != m_PendingJobs.end();) + { + Job* job = *iter; + job->Process(); + if (job->IsFinished()) + { + _lock(m_FinishedMutex) { + m_FinishedJobs.push_back(job); + } + iter = m_PendingJobs.erase(iter); + continue; + } + ++iter; + } + if (m_PendingJobs.size() == 0) + ::Sleep(1); + } + } +} + +void WorkThread::Dispatch(void* param) +{ + _lock(m_FinishedMutex) + { + for (int i = 0; i < m_FinishedJobs.size(); ++i) + { + m_FinishedJobs[i]->Dispacth(param); + } + m_FinishedJobs.clear(); + } +} + +void WorkThread::AddJobAtEnd(Job* job) +{ + _lock(m_PendingMutex) + { + m_PendingJobs.push_back(job); + } +}
\ No newline at end of file diff --git a/Runtime/Threads/Thread.h b/Runtime/Threads/Thread.h deleted file mode 100644 index e69de29..0000000 --- a/Runtime/Threads/Thread.h +++ /dev/null |