summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/3rd-party/Luax/luax_class.hpp4
-rw-r--r--source/3rd-party/Luax/luax_config.h4
-rw-r--r--source/3rd-party/Luax/luax_state.h37
-rw-r--r--source/Asura.Editor/system/file_watcher.h517
-rw-r--r--source/libs/asura-lib-core/graphics/binding/_image.cpp57
-rw-r--r--source/libs/asura-lib-core/graphics/binding/_image_decode_task.cpp21
-rw-r--r--source/libs/asura-lib-core/graphics/binding/_window.cpp103
-rw-r--r--source/libs/asura-lib-core/graphics/image.h15
-rw-r--r--source/libs/asura-lib-core/graphics/window.h19
-rw-r--r--source/libs/asura-lib-core/graphics/window_impl_glew.cpp0
-rw-r--r--source/libs/asura-lib-core/graphics/window_impl_glew.h0
-rw-r--r--source/libs/asura-lib-core/graphics/window_impl_glut.cpp0
-rw-r--r--source/libs/asura-lib-core/graphics/window_impl_glut.h0
-rw-r--r--source/libs/asura-lib-core/threading/coroutine.cpp0
-rw-r--r--source/libs/asura-lib-core/threading/coroutine.h31
-rw-r--r--source/libs/asura-lib-core/threading/thread.cpp0
-rw-r--r--source/libs/asura-lib-core/threading/thread.h53
-rw-r--r--source/libs/asura-lib-core/threading/thread_impl_posix.cpp0
-rw-r--r--source/libs/asura-lib-core/threading/thread_impl_posix.h0
-rw-r--r--source/libs/asura-lib-core/threading/thread_impl_sdl.cpp0
-rw-r--r--source/libs/asura-lib-core/threading/thread_impl_sdl.h0
-rw-r--r--source/libs/asura-lib-core/threading/thread_impl_std.cpp0
-rw-r--r--source/libs/asura-lib-core/threading/thread_impl_std.h0
-rw-r--r--source/libs/asura-lib-core/threading/thread_impl_win32.cpp0
-rw-r--r--source/libs/asura-lib-core/threading/thread_impl_win32.h25
-rw-r--r--source/libs/asura-lib-core/threading/thread_task.cpp0
-rw-r--r--source/libs/asura-lib-core/threading/thread_task.h25
-rw-r--r--source/libs/asura-lib-utils/io/binding/_io_task.cpp36
-rw-r--r--source/libs/asura-lib-utils/io/data_buffer.cpp9
-rw-r--r--source/libs/asura-lib-utils/io/data_buffer.h3
-rw-r--r--source/libs/asura-lib-utils/io/file.h11
-rw-r--r--source/libs/asura-lib-utils/io/io_task.cpp29
-rw-r--r--source/libs/asura-lib-utils/io/io_task.h10
-rw-r--r--source/libs/asura-lib-utils/math/quaternion.cpp0
-rw-r--r--source/libs/asura-lib-utils/math/quaternion.h0
-rw-r--r--source/libs/asura-lib-utils/threading/binding/_coroutine.cpp40
-rw-r--r--source/libs/asura-lib-utils/threading/binding/_thread.cpp104
-rw-r--r--source/libs/asura-lib-utils/threading/coroutine.h2
-rw-r--r--source/libs/asura-lib-utils/threading/mutex.cpp81
-rw-r--r--source/libs/asura-lib-utils/threading/mutex.h84
-rw-r--r--source/libs/asura-lib-utils/threading/thread.cpp81
-rw-r--r--source/libs/asura-lib-utils/threading/thread.h58
-rw-r--r--source/libs/asura-lib-utils/threading/thread_impl_std.h43
-rw-r--r--source/libs/asura-lib-utils/threading/thread_impl_win32.cpp69
-rw-r--r--source/libs/asura-lib-utils/threading/thread_impl_win32.h13
-rw-r--r--source/libs/asura-lib-utils/threading/thread_task.h19
-rw-r--r--source/libs/asura-lib-utils/utils_config.h1
47 files changed, 1571 insertions, 33 deletions
diff --git a/source/3rd-party/Luax/luax_class.hpp b/source/3rd-party/Luax/luax_class.hpp
index af52b5f..cfac2a5 100644
--- a/source/3rd-party/Luax/luax_class.hpp
+++ b/source/3rd-party/Luax/luax_class.hpp
@@ -81,6 +81,10 @@ namespace Luax
///
virtual bool PushLuaxMemberRef(LuaxState& state, int refID) { assert(false); return false; };
+ virtual bool PushLuaxUserdata(LuaxState& state) { assert(false); return false; };
+ virtual bool PushLuaxMemberTable(LuaxState& state) { assert(false); return false; };
+ virtual bool PushLuaxRefTable(LuaxState& state) { assert(false); return false; };
+
};
///
diff --git a/source/3rd-party/Luax/luax_config.h b/source/3rd-party/Luax/luax_config.h
index d95ae8b..0ace00b 100644
--- a/source/3rd-party/Luax/luax_config.h
+++ b/source/3rd-party/Luax/luax_config.h
@@ -52,8 +52,8 @@ namespace Luax
#define LUAX_ENABLE_NATIVE_EXTEND 0
-#define LUAX_ENABLE_PLAIN_CLASS 1
-#define LUAX_ENABLE_PLAIN_ENUM 1
+#define LUAX_ENABLE_PLAIN_CLASS 0
+#define LUAX_ENABLE_PLAIN_ENUM 0
}
diff --git a/source/3rd-party/Luax/luax_state.h b/source/3rd-party/Luax/luax_state.h
index 20d5189..e9c394a 100644
--- a/source/3rd-party/Luax/luax_state.h
+++ b/source/3rd-party/Luax/luax_state.h
@@ -193,13 +193,13 @@ namespace Luax
//------------------------------------------------------------------------------------------------------------
- private:
+ protected:
friend class LuaxContext;
LuaxState(lua_State* state);
LuaxState(const LuaxState& state);
- ~LuaxState();
+ virtual ~LuaxState();
///
/// ζLuaxStateĵַز
@@ -258,6 +258,39 @@ namespace Luax
#define LUAX_STATE(L) \
Luax::LuaxState& state = Luax::LuaxRuntime::Get().GetLuaxState(L)
+ //--------------------------------------------------------------------------------------------------------------
+
+ ///
+ /// ȷȫluaܹڵ֮󷵻صstack״̬
+ ///
+ class LuaxScopedState
+ : public LuaxState
+ {
+ public:
+ LuaxScopedState(lua_State* state)
+ : LuaxState(state)
+ {
+ mRestoreTop = lua_gettop(mState);
+ }
+ LuaxScopedState(const LuaxState& state)
+ : LuaxState(state)
+ {
+ mRestoreTop = lua_gettop(mState);
+ }
+ ~LuaxScopedState()
+ {
+ if (mState) {
+ if (lua_gettop(mState) != mRestoreTop) {
+ lua_settop(mState, mRestoreTop);
+ }
+ }
+ }
+ private:
+ void* operator new(size_t);
+ int mRestoreTop;
+
+ };
+
}
#endif \ No newline at end of file
diff --git a/source/Asura.Editor/system/file_watcher.h b/source/Asura.Editor/system/file_watcher.h
index e69de29..43821da 100644
--- a/source/Asura.Editor/system/file_watcher.h
+++ b/source/Asura.Editor/system/file_watcher.h
@@ -0,0 +1,517 @@
+// MIT License
+//
+// Copyright(c) 2017 Thomas Monkman
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#ifndef FILEWATCHER_H
+#define FILEWATCHER_H
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <tchar.h>
+#include <Pathcch.h>
+#include <shlwapi.h>
+#endif // WIN32
+
+#if __unix__
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/inotify.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#endif // __unix__
+
+#include <functional>
+#include <atomic>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <utility>
+#include <vector>
+#include <array>
+#include <map>
+#include <system_error>
+#include <string>
+#include <algorithm>
+#include <type_traits>
+#include <future>
+#include <regex>
+
+namespace filewatch {
+ enum class Event {
+ added,
+ removed,
+ modified,
+ renamed_old,
+ renamed_new
+ };
+
+ /**
+ * \class FileWatch
+ *
+ * \brief Watches a folder or file, and will notify of changes via function callback.
+ *
+ * \author Thomas Monkman
+ *
+ */
+ template<class T>
+ class FileWatch
+ {
+ typedef std::basic_string<typename T::value_type, std::char_traits<typename T::value_type>> UnderpinningString;
+ typedef std::basic_regex<typename T::value_type, std::regex_traits<typename T::value_type>> UnderpinningRegex;
+
+ public:
+
+ FileWatch(T path, UnderpinningRegex pattern, std::function<void(const T& file, const Event event_type)> callback) :
+ _path(path),
+ _pattern(pattern),
+ _callback(callback),
+ _directory(get_directory(path))
+ {
+ init();
+ }
+
+#if defined _WIN32 && (defined UNICODE || defined _UNICODE)
+ FileWatch(T path, std::function<void(const T& file, const Event event_type)> callback) :
+ FileWatch<T>(path, UnderpinningRegex(L".*"), callback) {}
+#else // _WIN32 && (UNICODE || _UNICODE)
+ FileWatch(T path, std::function<void(const T& file, const Event event_type)> callback) :
+ FileWatch<T>(path, UnderpinningRegex(".*"), callback) {}
+#endif
+
+ ~FileWatch() {
+ destroy();
+ }
+
+ FileWatch(const FileWatch<T>& other) : FileWatch<T>(other._path, other._callback) {}
+
+ FileWatch<T>& operator=(const FileWatch<T>& other)
+ {
+ if (this == &other) { return *this; }
+
+ destroy();
+ _path = other._path;
+ _callback = other._callback;
+ _directory = get_directory(other._path);
+ init();
+ return *this;
+ }
+
+ // Const memeber varibles don't let me implent moves nicely, if moves are really wanted std::unique_ptr should be used and move that.
+ FileWatch<T>(FileWatch<T>&&) = delete;
+ FileWatch<T>& operator=(FileWatch<T>&&) & = delete;
+
+ private:
+ struct PathParts
+ {
+ PathParts(T directory, T filename) : directory(directory), filename(filename) {}
+ T directory;
+ T filename;
+ };
+ const T _path;
+
+ UnderpinningRegex _pattern;
+
+ static constexpr std::size_t _buffer_size = { 1024 * 256 };
+
+ // only used if watch a single file
+ bool _watching_single_file = { false };
+ T _filename;
+
+ std::atomic<bool> _destory = { false };
+ std::function<void(const T& file, const Event event_type)> _callback;
+
+ std::thread _watch_thread;
+
+ std::condition_variable _cv;
+ std::mutex _callback_mutex;
+ std::vector<std::pair<T, Event>> _callback_information;
+ std::thread _callback_thread;
+
+ std::promise<void> _running;
+#ifdef _WIN32
+ HANDLE _directory = { nullptr };
+ HANDLE _close_event = { nullptr };
+
+ const DWORD _listen_filters =
+ FILE_NOTIFY_CHANGE_SECURITY |
+ FILE_NOTIFY_CHANGE_CREATION |
+ FILE_NOTIFY_CHANGE_LAST_ACCESS |
+ FILE_NOTIFY_CHANGE_LAST_WRITE |
+ FILE_NOTIFY_CHANGE_SIZE |
+ FILE_NOTIFY_CHANGE_ATTRIBUTES |
+ FILE_NOTIFY_CHANGE_DIR_NAME |
+ FILE_NOTIFY_CHANGE_FILE_NAME;
+
+ const std::map<DWORD, Event> _event_type_mapping = {
+ { FILE_ACTION_ADDED, Event::added },
+ { FILE_ACTION_REMOVED, Event::removed },
+ { FILE_ACTION_MODIFIED, Event::modified },
+ { FILE_ACTION_RENAMED_OLD_NAME, Event::renamed_old },
+ { FILE_ACTION_RENAMED_NEW_NAME, Event::renamed_new }
+ };
+#endif // WIN32
+
+#if __unix__
+ struct FolderInfo {
+ int folder;
+ int watch;
+ };
+
+ FolderInfo _directory;
+
+ const std::uint32_t _listen_filters = IN_MODIFY | IN_CREATE | IN_DELETE;
+
+ const static std::size_t event_size = (sizeof(struct inotify_event));
+#endif // __unix__
+
+ void init()
+ {
+#ifdef _WIN32
+ _close_event = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (!_close_event) {
+ throw std::system_error(GetLastError(), std::system_category());
+ }
+#endif // WIN32
+ _callback_thread = std::move(std::thread([this]() {
+ try {
+ callback_thread();
+ }
+ catch (...) {
+ try {
+ _running.set_exception(std::current_exception());
+ }
+ catch (...) {} // set_exception() may throw too
+ }
+ }));
+ _watch_thread = std::move(std::thread([this]() {
+ try {
+ monitor_directory();
+ }
+ catch (...) {
+ try {
+ _running.set_exception(std::current_exception());
+ }
+ catch (...) {} // set_exception() may throw too
+ }
+ }));
+
+ std::future<void> future = _running.get_future();
+ future.get(); //block until the monitor_directory is up and running
+ }
+
+ void destroy()
+ {
+ _destory = true;
+ _running = std::promise<void>();
+#ifdef _WIN32
+ SetEvent(_close_event);
+#elif __unix__
+ inotify_rm_watch(_directory.folder, _directory.watch);
+#endif // __unix__
+ _cv.notify_all();
+ _watch_thread.join();
+ _callback_thread.join();
+#ifdef _WIN32
+ CloseHandle(_directory);
+#elif __unix__
+ close(_directory.folder);
+#endif // __unix__
+ }
+
+ const PathParts split_directory_and_file(const T& path) const
+ {
+ const auto predict = [](typename T::value_type character) {
+#ifdef _WIN32
+ return character == _T('\\') || character == _T('/');
+#elif __unix__
+ return character == '/';
+#endif // __unix__
+ };
+#ifdef _WIN32
+#define _UNICODE
+ const UnderpinningString this_directory = _T("./");
+#elif __unix__
+ const UnderpinningString this_directory = "./";
+#endif // __unix__
+
+ const auto pivot = std::find_if(path.rbegin(), path.rend(), predict).base();
+ //if the path is something like "test.txt" there will be no directoy part, however we still need one, so insert './'
+ const T directory = [&]() {
+ const auto extracted_directory = UnderpinningString(path.begin(), pivot);
+ return (extracted_directory.size() > 0) ? extracted_directory : this_directory;
+ }();
+ const T filename = UnderpinningString(pivot, path.end());
+ return PathParts(directory, filename);
+ }
+
+ bool pass_filter(const UnderpinningString& file_path)
+ {
+ if (_watching_single_file) {
+ const UnderpinningString extracted_filename = { split_directory_and_file(file_path).filename };
+ //if we are watching a single file, only that file should trigger action
+ return extracted_filename == _filename;
+ }
+ return std::regex_match(file_path, _pattern);
+ }
+
+#ifdef _WIN32
+ HANDLE get_directory(const T& path)
+ {
+ auto file_info = GetFileAttributes(path.c_str());
+
+ if (file_info == INVALID_FILE_ATTRIBUTES)
+ {
+ throw std::system_error(GetLastError(), std::system_category());
+ }
+ _watching_single_file = (file_info & FILE_ATTRIBUTE_DIRECTORY) == false;
+
+ const T watch_path = [this, &path]() {
+ if (_watching_single_file)
+ {
+ const auto parsed_path = split_directory_and_file(path);
+ _filename = parsed_path.filename;
+ return parsed_path.directory;
+ }
+ else
+ {
+ return path;
+ }
+ }();
+
+ HANDLE directory = ::CreateFile(
+ watch_path.c_str(), // pointer to the file name
+ FILE_LIST_DIRECTORY, // access (read/write) mode
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, // share mode
+ NULL, // security descriptor
+ OPEN_EXISTING, // how to create
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, // file attributes
+ NULL); // file with attributes to copy
+
+ if (directory == INVALID_HANDLE_VALUE)
+ {
+ throw std::system_error(GetLastError(), std::system_category());
+ }
+ return directory;
+ }
+ void monitor_directory()
+ {
+ std::vector<BYTE> buffer(_buffer_size);
+ DWORD bytes_returned = 0;
+ OVERLAPPED overlapped_buffer{ 0 };
+
+ overlapped_buffer.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (!overlapped_buffer.hEvent) {
+ std::cerr << "Error creating monitor event" << std::endl;
+ }
+
+ std::array<HANDLE, 2> handles{ overlapped_buffer.hEvent, _close_event };
+
+ auto async_pending = false;
+ _running.set_value();
+ do {
+ std::vector<std::pair<T, Event>> parsed_information;
+ ReadDirectoryChangesW(
+ _directory,
+ buffer.data(), buffer.size(),
+ TRUE,
+ _listen_filters,
+ &bytes_returned,
+ &overlapped_buffer, NULL);
+
+ async_pending = true;
+
+ switch (WaitForMultipleObjects(2, handles.data(), FALSE, INFINITE))
+ {
+ case WAIT_OBJECT_0:
+ {
+ if (!GetOverlappedResult(_directory, &overlapped_buffer, &bytes_returned, TRUE)) {
+ throw std::system_error(GetLastError(), std::system_category());
+ }
+ async_pending = false;
+
+ if (bytes_returned == 0) {
+ break;
+ }
+
+ FILE_NOTIFY_INFORMATION *file_information = reinterpret_cast<FILE_NOTIFY_INFORMATION*>(&buffer[0]);
+ do
+ {
+ UnderpinningString changed_file{ file_information->FileName, file_information->FileNameLength / 2 };
+ if (pass_filter(changed_file))
+ {
+ parsed_information.emplace_back(T{ changed_file }, _event_type_mapping.at(file_information->Action));
+ }
+
+ if (file_information->NextEntryOffset == 0) {
+ break;
+ }
+
+ file_information = reinterpret_cast<FILE_NOTIFY_INFORMATION*>(reinterpret_cast<BYTE*>(file_information) + file_information->NextEntryOffset);
+ } while (true);
+ break;
+ }
+ case WAIT_OBJECT_0 + 1:
+ // quit
+ break;
+ case WAIT_FAILED:
+ break;
+ }
+ //dispatch callbacks
+ {
+ std::lock_guard<std::mutex> lock(_callback_mutex);
+ _callback_information.insert(_callback_information.end(), parsed_information.begin(), parsed_information.end());
+ }
+ _cv.notify_all();
+ } while (_destory == false);
+
+ if (async_pending)
+ {
+ //clean up running async io
+ CancelIo(_directory);
+ GetOverlappedResult(_directory, &overlapped_buffer, &bytes_returned, TRUE);
+ }
+ }
+#endif // WIN32
+
+#if __unix__
+
+ bool is_file(const T& path) const
+ {
+ struct stat statbuf = {};
+ if (stat(path.c_str(), &statbuf) != 0)
+ {
+ throw std::system_error(errno, std::system_category());
+ }
+ return S_ISREG(statbuf.st_mode);
+ }
+
+ FolderInfo get_directory(const T& path)
+ {
+ const auto folder = inotify_init();
+ if (folder < 0)
+ {
+ throw std::system_error(errno, std::system_category());
+ }
+ const auto listen_filters = _listen_filters;
+
+ _watching_single_file = is_file(path);
+
+ const T watch_path = [this, &path]() {
+ if (_watching_single_file)
+ {
+ const auto parsed_path = split_directory_and_file(path);
+ _filename = parsed_path.filename;
+ return parsed_path.directory;
+ }
+ else
+ {
+ return path;
+ }
+ }();
+
+ const auto watch = inotify_add_watch(folder, watch_path.c_str(), IN_MODIFY | IN_CREATE | IN_DELETE);
+ if (watch < 0)
+ {
+ throw std::system_error(errno, std::system_category());
+ }
+ return { folder, watch };
+ }
+
+ void monitor_directory()
+ {
+ std::vector<char> buffer(_buffer_size);
+
+ _running.set_value();
+ while (_destory == false)
+ {
+ const auto length = read(_directory.folder, static_cast<void*>(buffer.data()), buffer.size());
+ if (length > 0)
+ {
+ int i = 0;
+ std::vector<std::pair<T, Event>> parsed_information;
+ while (i < length)
+ {
+ struct inotify_event *event = reinterpret_cast<struct inotify_event *>(&buffer[i]); // NOLINT
+ if (event->len)
+ {
+ const UnderpinningString changed_file{ event->name };
+ if (pass_filter(changed_file))
+ {
+ if (event->mask & IN_CREATE)
+ {
+ parsed_information.emplace_back(T{ changed_file }, Event::added);
+ }
+ else if (event->mask & IN_DELETE)
+ {
+ parsed_information.emplace_back(T{ changed_file }, Event::removed);
+ }
+ else if (event->mask & IN_MODIFY)
+ {
+ parsed_information.emplace_back(T{ changed_file }, Event::modified);
+ }
+ }
+ }
+ i += event_size + event->len;
+ }
+ //dispatch callbacks
+ {
+ std::lock_guard<std::mutex> lock(_callback_mutex);
+ _callback_information.insert(_callback_information.end(), parsed_information.begin(), parsed_information.end());
+ }
+ _cv.notify_all();
+ }
+ }
+ }
+#endif // __unix__
+
+ void callback_thread()
+ {
+ while (_destory == false) {
+ std::unique_lock<std::mutex> lock(_callback_mutex);
+ if (_callback_information.empty() && _destory == false) {
+ _cv.wait(lock, [this] { return _callback_information.size() > 0 || _destory; });
+ }
+ decltype(_callback_information) callback_information = {};
+ std::swap(callback_information, _callback_information);
+ lock.unlock();
+
+ for (const auto& file : callback_information) {
+ if (_callback) {
+ try
+ {
+ _callback(file.first, file.second);
+ }
+ catch (const std::exception&)
+ {
+ }
+ }
+ }
+ }
+ }
+ };
+}
+#endif \ No newline at end of file
diff --git a/source/libs/asura-lib-core/graphics/binding/_image.cpp b/source/libs/asura-lib-core/graphics/binding/_image.cpp
index 7c1034c..b455ad5 100644
--- a/source/libs/asura-lib-core/graphics/binding/_image.cpp
+++ b/source/libs/asura-lib-core/graphics/binding/_image.cpp
@@ -10,10 +10,13 @@ namespace AsuraEngine
LUAX_REGISTRY(Image)
{
LUAX_REGISTER_METHODS(state,
+ { "New", _New },
{ "Load", _Load },
{ "GetWidth", _GetWidth },
{ "GetHeight", _GetHeight },
- { "GetSize", _GetSize }
+ { "GetSize", _GetSize },
+ { "GetPixel", _GetPixel },
+ { "Render", _Render }
);
}
@@ -22,33 +25,75 @@ namespace AsuraEngine
}
- // image:Load()
+ // image = Image.New()
+ LUAX_IMPL_METHOD(Image, _New)
+ {
+ LUAX_STATE(L);
+
+ Image* image = new Image();
+ image->PushLuaxUserdata(state);
+ return 0;
+ }
+
+ // successed = image:Load(image_data)
LUAX_IMPL_METHOD(Image, _Load)
{
LUAX_PREPARE(L, Image);
+ ImageData* imgdata = state.CheckUserdata<ImageData>(2);
+ bool loaded = self->Load(imgdata);
+ state.Push(loaded);
+ return 1;
}
- // image:GetWidth()
+ // width = image:GetWidth()
LUAX_IMPL_METHOD(Image, _GetWidth)
{
LUAX_PREPARE(L, Image);
+ state.Push(self->GetWidth());
+ return 1;
}
- // image:GetHeight()
+ // height = image:GetHeight()
LUAX_IMPL_METHOD(Image, _GetHeight)
{
LUAX_PREPARE(L, Image);
+ state.Push(self->GetHeight());
+ return 1;
}
- // image:GetSize()
+ // w, h = image:GetSize()
LUAX_IMPL_METHOD(Image, _GetSize)
{
LUAX_PREPARE(L, Image);
+ Math::Vector2u size = self->GetSize();
+ state.Push(size.x);
+ state.Push(size.y);
+ return 2;
+ }
+
+ // color32 = image:GetPixel(x, y)
+ LUAX_IMPL_METHOD(Image, _GetPixel)
+ {
+ LUAX_PREPARE(L, Image);
+
+ uint x = state.CheckParam<uint>(2);
+ uint y = state.CheckParam<uint>(3);
+ Color32* c32 = new Color32(self->GetPixel(x, y));
+ c32->PushLuaxUserdata(state);
+ return 1;
+ }
+
+ // image:Render()
+ LUAX_IMPL_METHOD(Image, _Render)
+ {
+ LUAX_PREPARE(L, Image);
+
+ return 0;
}
}
-}
+} \ No newline at end of file
diff --git a/source/libs/asura-lib-core/graphics/binding/_image_decode_task.cpp b/source/libs/asura-lib-core/graphics/binding/_image_decode_task.cpp
new file mode 100644
index 0000000..76b544b
--- /dev/null
+++ b/source/libs/asura-lib-core/graphics/binding/_image_decode_task.cpp
@@ -0,0 +1,21 @@
+#include "../image_decode_task.h"
+
+using namespace std;
+
+namespace AsuraEngine
+{
+ namespace Graphics
+ {
+
+ LUAX_REGISTRY(ImageDecodeTask)
+ {
+
+ }
+
+ LUAX_POSTPROCESS(ImageDecodeTask)
+ {
+
+ }
+
+ }
+}
diff --git a/source/libs/asura-lib-core/graphics/binding/_window.cpp b/source/libs/asura-lib-core/graphics/binding/_window.cpp
new file mode 100644
index 0000000..fc74d6c
--- /dev/null
+++ b/source/libs/asura-lib-core/graphics/binding/_window.cpp
@@ -0,0 +1,103 @@
+#include "../window.h"
+
+using namespace std;
+
+namespace AsuraEngine
+{
+ namespace Graphics
+ {
+
+ LUAX_REGISTRY(Window)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "Show", _Show },
+ { "Hide", _Hide },
+ { "SetResolution", _SetResolution },
+ { "SetFullScreen", _SetFullScreen },
+ { "SetTitle", _SetTitle },
+ { "SetWindowStyle", _SetWindowStyle },
+ { "Clear", _Clear },
+ { "Draw", _Draw },
+ { "SwapRenderBuffer", _SwapRenderBuffer }
+ );
+ }
+
+ LUAX_POSTPROCESS(Window)
+ {
+
+ }
+
+ // window:Show()
+ LUAX_IMPL_METHOD(Window, _Show)
+ {
+ LUAX_PREPARE(L, Window);
+
+ return 0;
+ }
+
+ // window:Hide()
+ LUAX_IMPL_METHOD(Window, _Hide)
+ {
+ LUAX_PREPARE(L, Window);
+
+ return 0;
+ }
+
+ // window:SetResolution()
+ LUAX_IMPL_METHOD(Window, _SetResolution)
+ {
+ LUAX_PREPARE(L, Window);
+
+ return 0;
+ }
+
+ // window:SetFullScreen()
+ LUAX_IMPL_METHOD(Window, _SetFullScreen)
+ {
+ LUAX_PREPARE(L, Window);
+
+ return 0;
+ }
+
+ // window:SetTitle()
+ LUAX_IMPL_METHOD(Window, _SetTitle)
+ {
+ LUAX_PREPARE(L, Window);
+
+ return 0;
+ }
+
+ // window:SetWindowStyle()
+ LUAX_IMPL_METHOD(Window, _SetWindowStyle)
+ {
+ LUAX_PREPARE(L, Window);
+
+ return 0;
+ }
+
+ // window:Clear()
+ LUAX_IMPL_METHOD(Window, _Clear)
+ {
+ LUAX_PREPARE(L, Window);
+
+ return 0;
+ }
+
+ // window:Draw()
+ LUAX_IMPL_METHOD(Window, _Draw)
+ {
+ LUAX_PREPARE(L, Window);
+
+ return 0;
+ }
+
+ // window:SwapRenderBuffer()
+ LUAX_IMPL_METHOD(Window, _SwapRenderBuffer)
+ {
+ LUAX_PREPARE(L, Window);
+
+ return 0;
+ }
+
+ }
+}
diff --git a/source/libs/asura-lib-core/graphics/image.h b/source/libs/asura-lib-core/graphics/image.h
index 0e4ea0a..4c1c7b5 100644
--- a/source/libs/asura-lib-core/graphics/image.h
+++ b/source/libs/asura-lib-core/graphics/image.h
@@ -10,6 +10,7 @@
#include "texture.h"
#include "color.h"
+#include "color32.h"
#include "image_data.h"
#include "render_state.h"
@@ -31,6 +32,8 @@ namespace AsuraEngine
{
public:
+ LUAX_DECL_FACTORY(SimImage);
+
Image();
~Image();
@@ -56,21 +59,21 @@ namespace AsuraEngine
private:
- ImageData* mImageData;
+ ImageData* mImageData;
+ Luax::LuaxMemberRef mImageDataRef;
Math::Vector2u mSize;
- public:
-
- LUAX_DECL_FACTORY(SimImage);
-
+ LUAX_DECL_METHOD(_New);
LUAX_DECL_METHOD(_Load);
LUAX_DECL_METHOD(_GetWidth);
LUAX_DECL_METHOD(_GetHeight);
LUAX_DECL_METHOD(_GetSize);
+ LUAX_DECL_METHOD(_GetPixel);
+ LUAX_DECL_METHOD(_Render);
};
-
+
}
}
diff --git a/source/libs/asura-lib-core/graphics/window.h b/source/libs/asura-lib-core/graphics/window.h
index 0bfd6a1..1b219a2 100644
--- a/source/libs/asura-lib-core/graphics/window.h
+++ b/source/libs/asura-lib-core/graphics/window.h
@@ -12,15 +12,16 @@ namespace AsuraEngine
namespace Graphics
{
+ class WindowImpl;
+
enum WindowStyle
{
WINDOW_STYLE_FULLSCREEN = 1 << 1,
};
- class WindowImpl;
-
///
- /// ڣֶ֧രڡڱ༭Ҫ֧֣runnerֻҪһڡͬĿͻʵִ˽ӿڲֶעᵽlua
+ /// ϷĵڣrunnerֻҪһڡͬĿͻʵִ˽ӿڲֶעᵽlua༭ᵼ࣬޽ӵ༭
+ /// ⴰϡ
///
class Window
: public RenderTarget
@@ -63,6 +64,16 @@ namespace AsuraEngine
WindowImpl* mImpl;
+ LUAX_DECL_METHOD(_Show);
+ LUAX_DECL_METHOD(_Hide);
+ LUAX_DECL_METHOD(_SetResolution);
+ LUAX_DECL_METHOD(_SetFullScreen);
+ LUAX_DECL_METHOD(_SetTitle);
+ LUAX_DECL_METHOD(_SetWindowStyle);
+ LUAX_DECL_METHOD(_Clear);
+ LUAX_DECL_METHOD(_Draw);
+ LUAX_DECL_METHOD(_SwapRenderBuffer);
+
};
using RenderWindow = Window;
@@ -71,8 +82,6 @@ namespace AsuraEngine
{
public:
-
-
};
}
diff --git a/source/libs/asura-lib-core/graphics/window_impl_glew.cpp b/source/libs/asura-lib-core/graphics/window_impl_glew.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/graphics/window_impl_glew.cpp
diff --git a/source/libs/asura-lib-core/graphics/window_impl_glew.h b/source/libs/asura-lib-core/graphics/window_impl_glew.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/graphics/window_impl_glew.h
diff --git a/source/libs/asura-lib-core/graphics/window_impl_glut.cpp b/source/libs/asura-lib-core/graphics/window_impl_glut.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/graphics/window_impl_glut.cpp
diff --git a/source/libs/asura-lib-core/graphics/window_impl_glut.h b/source/libs/asura-lib-core/graphics/window_impl_glut.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/graphics/window_impl_glut.h
diff --git a/source/libs/asura-lib-core/threading/coroutine.cpp b/source/libs/asura-lib-core/threading/coroutine.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/coroutine.cpp
diff --git a/source/libs/asura-lib-core/threading/coroutine.h b/source/libs/asura-lib-core/threading/coroutine.h
new file mode 100644
index 0000000..1ac6b21
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/coroutine.h
@@ -0,0 +1,31 @@
+#ifndef __ASURA_COROUTINE_H__
+#define __ASURA_COROUTINE_H__
+
+#include <asura-lib-utils/scripting/portable.hpp>
+
+namespace AsuraEngine
+{
+ namespace Threading
+ {
+
+ ///
+ /// luaЭ̣һЩ߼
+ ///
+ class Coroutine ASURA_FINAL
+ : public AEScripting::Portable<Coroutine>
+ {
+ public:
+
+ LUAX_DECL_FACTORY(Coroutine);
+
+ private:
+
+ LUAX_DECL_METHOD(_New);
+ LUAX_DECL_METHOD(_Run);
+
+ };
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/source/libs/asura-lib-core/threading/thread.cpp b/source/libs/asura-lib-core/threading/thread.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/thread.cpp
diff --git a/source/libs/asura-lib-core/threading/thread.h b/source/libs/asura-lib-core/threading/thread.h
new file mode 100644
index 0000000..f4d3b48
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/thread.h
@@ -0,0 +1,53 @@
+#ifndef __ASURA_THREAD_H__
+#define __ASURA_THREAD_H__
+
+#include <queue>
+#include <asura-lib-utils/scripting/portable.hpp>
+
+#include "thread_task.h"
+
+namespace AsuraEngine
+{
+ namespace Threading
+ {
+
+ ///
+ /// ̵߳ľʵ֣û͸ģһ׼ֲԣ
+ /// 1: win32
+ /// 2: posix
+ /// 3: SDL
+ /// 4: std::thread
+ ///
+ ASURA_ABSTRACT class ThreadImpl
+ {
+ public:
+
+ };
+
+ ///
+ /// ߳壬ÿ߳άһtask queue
+ ///
+ class Thread ASURA_FINAL
+ : public AEScripting::Portable<Thread>
+ {
+ public:
+
+ LUAX_DECL_FACTORY(Thread);
+
+ bool Enqueue(ThreadTask* task);
+
+ private:
+
+ ///
+ /// С
+ ///
+ std::queue<ThreadTask*> mTaskQueue;
+
+ ThreadImpl* mImpl;
+
+ };
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/source/libs/asura-lib-core/threading/thread_impl_posix.cpp b/source/libs/asura-lib-core/threading/thread_impl_posix.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/thread_impl_posix.cpp
diff --git a/source/libs/asura-lib-core/threading/thread_impl_posix.h b/source/libs/asura-lib-core/threading/thread_impl_posix.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/thread_impl_posix.h
diff --git a/source/libs/asura-lib-core/threading/thread_impl_sdl.cpp b/source/libs/asura-lib-core/threading/thread_impl_sdl.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/thread_impl_sdl.cpp
diff --git a/source/libs/asura-lib-core/threading/thread_impl_sdl.h b/source/libs/asura-lib-core/threading/thread_impl_sdl.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/thread_impl_sdl.h
diff --git a/source/libs/asura-lib-core/threading/thread_impl_std.cpp b/source/libs/asura-lib-core/threading/thread_impl_std.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/thread_impl_std.cpp
diff --git a/source/libs/asura-lib-core/threading/thread_impl_std.h b/source/libs/asura-lib-core/threading/thread_impl_std.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/thread_impl_std.h
diff --git a/source/libs/asura-lib-core/threading/thread_impl_win32.cpp b/source/libs/asura-lib-core/threading/thread_impl_win32.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/thread_impl_win32.cpp
diff --git a/source/libs/asura-lib-core/threading/thread_impl_win32.h b/source/libs/asura-lib-core/threading/thread_impl_win32.h
new file mode 100644
index 0000000..5d854cc
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/thread_impl_win32.h
@@ -0,0 +1,25 @@
+#ifndef __ASURA_THREAD_WIN32_H__
+#define __ASURA_THREAD_WIN32_H__
+
+#include "../core_config.h"
+
+#include "thread.h"
+
+#if ASURA_THREAD_WIN32
+
+namespace AsuraEngine
+{
+ namespace Threading
+ {
+
+ class ThreadImplWin32 : public ThreadImpl
+ {
+
+ };
+
+ }
+}
+
+#endif // #if ASURA_THREAD_WIN32
+
+#endif \ No newline at end of file
diff --git a/source/libs/asura-lib-core/threading/thread_task.cpp b/source/libs/asura-lib-core/threading/thread_task.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/thread_task.cpp
diff --git a/source/libs/asura-lib-core/threading/thread_task.h b/source/libs/asura-lib-core/threading/thread_task.h
new file mode 100644
index 0000000..19eb113
--- /dev/null
+++ b/source/libs/asura-lib-core/threading/thread_task.h
@@ -0,0 +1,25 @@
+#ifndef __ASURA_THRAD_TASK_H__
+#define __ASURA_THRAD_TASK_H__
+
+#include <asura-lib-utils/type.h>
+
+namespace AsuraEngine
+{
+ namespace Threading
+ {
+
+ ///
+ /// ϣһ̴߳񣬼̳TaskдExecute
+ ///
+ ASURA_ABSTRACT class ThreadTask
+ {
+ public:
+
+ virtual bool Execute() = 0;
+
+ };
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/source/libs/asura-lib-utils/io/binding/_io_task.cpp b/source/libs/asura-lib-utils/io/binding/_io_task.cpp
new file mode 100644
index 0000000..c03ff2a
--- /dev/null
+++ b/source/libs/asura-lib-utils/io/binding/_io_task.cpp
@@ -0,0 +1,36 @@
+#include "../io_task.h"
+
+using namespace std;
+
+namespace AsuraEngine
+{
+ namespace IO
+ {
+
+ LUAX_REGISTRY(IOTask)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "New", _New }
+ );
+ }
+
+ LUAX_POSTPROCESS(IOTask)
+ {
+
+ }
+
+ // task = IOTask.New(path, dst)
+ LUAX_IMPL_METHOD(IOTask, _New)
+ {
+ LUAX_STATE(L);
+
+ cc8* path = state.CheckParam<cc8*>(1);
+ DataBuffer* db = state.CheckUserdata<DataBuffer>(2);
+ IOTask* task = new IOTask(path, db);
+ task->PushLuaxUserdata(state);
+ task->SetLuaxMemberRef(state, task->mDstRef, 2);
+ return 1;
+ }
+
+ }
+}
diff --git a/source/libs/asura-lib-utils/io/data_buffer.cpp b/source/libs/asura-lib-utils/io/data_buffer.cpp
index 3c0100b..000869d 100644
--- a/source/libs/asura-lib-utils/io/data_buffer.cpp
+++ b/source/libs/asura-lib-utils/io/data_buffer.cpp
@@ -2,6 +2,8 @@
#include <cstring>
#include "data_buffer.h"
+using namespace AEThreading;
+
namespace AsuraEngine
{
namespace IO
@@ -16,6 +18,7 @@ namespace AsuraEngine
: mSize(size)
, mBytes(nullptr)
{
+ lock(mMutex);
mBytes = new byte[size];
memset(mBytes, 0, size);
}
@@ -34,6 +37,7 @@ namespace AsuraEngine
void DataBuffer::Refactor(size_t size)
{
+ lock(mMutex);
if (!mBytes || mSize != size)
{
delete[] mBytes;
@@ -50,6 +54,7 @@ namespace AsuraEngine
size_t DataBuffer::Load(const void* data, std::size_t size)
{
+ lock(mMutex);
size_t len = mSize > size ? size : mSize;
memcpy(mBytes, data, len);
return len;
@@ -57,6 +62,7 @@ namespace AsuraEngine
void DataBuffer::Move(void* bytes, std::size_t size)
{
+ lock(mMutex);
if (!mBytes)
{
delete[] mBytes;
@@ -72,10 +78,11 @@ namespace AsuraEngine
void DataBuffer::Clear()
{
+ lock(mMutex);
if (mBytes)
memset(mBytes, 0, mSize);
}
-
+
std::size_t DataBuffer::GetSize()
{
return mSize;
diff --git a/source/libs/asura-lib-utils/io/data_buffer.h b/source/libs/asura-lib-utils/io/data_buffer.h
index c63a248..9dfe541 100644
--- a/source/libs/asura-lib-utils/io/data_buffer.h
+++ b/source/libs/asura-lib-utils/io/data_buffer.h
@@ -4,6 +4,7 @@
#include <cstdlib>
#include "../scripting/portable.hpp"
+#include "../threading/mutex.h"
namespace AsuraEngine
{
@@ -39,6 +40,8 @@ namespace AsuraEngine
byte* mBytes;
size_t mSize;
+ AEThreading::Mutex mMutex;
+
LUAX_DECL_METHOD(_New);
LUAX_DECL_METHOD(_GetData);
LUAX_DECL_METHOD(_GetSize);
diff --git a/source/libs/asura-lib-utils/io/file.h b/source/libs/asura-lib-utils/io/file.h
index 4a6d38b..56077e0 100644
--- a/source/libs/asura-lib-utils/io/file.h
+++ b/source/libs/asura-lib-utils/io/file.h
@@ -4,6 +4,7 @@
#include "physfs/physfs.h"
#include "../scripting/portable.hpp"
+#include "../threading/thread.h"
#include "file_data.h"
@@ -58,6 +59,7 @@ namespace AsuraEngine
///
size_t Read(ASURA_OUT DataBuffer* dst, size_t length);
size_t ReadAll(ASURA_OUT DataBuffer* dst);
+ size_t ReadAsync(ASURA_OUT DataBuffer* dst);
///
/// Ƿļβ
@@ -70,6 +72,11 @@ namespace AsuraEngine
bool Write(ASURA_REF DataBuffer* src);
///
+ /// 첽дļдļtaskthreadĶС
+ ///
+ bool WriteAsync(ASURA_REF DataBuffer* src, AEThreading::Thread* thread);
+
+ ///
/// ˻壬ǿջдļ
///
bool Flush();
@@ -118,8 +125,10 @@ namespace AsuraEngine
LUAX_DECL_METHOD(_GetMode);
LUAX_DECL_METHOD(_GetSize);
LUAX_DECL_METHOD(_Read);
- LUAX_DECL_METHOD(_IsEOF);
LUAX_DECL_METHOD(_Write);
+ LUAX_DECL_METHOD(_ReadAsync);
+ LUAX_DECL_METHOD(_WriteAsync);
+ LUAX_DECL_METHOD(_IsEOF);
LUAX_DECL_METHOD(_Flush);
LUAX_DECL_METHOD(_Tell);
LUAX_DECL_METHOD(_Seek);
diff --git a/source/libs/asura-lib-utils/io/io_task.cpp b/source/libs/asura-lib-utils/io/io_task.cpp
index e69de29..a96c293 100644
--- a/source/libs/asura-lib-utils/io/io_task.cpp
+++ b/source/libs/asura-lib-utils/io/io_task.cpp
@@ -0,0 +1,29 @@
+#include "io_task.h"
+
+namespace AsuraEngine
+{
+ namespace IO
+ {
+
+ IOTask::IOTask(const std::string& path, DataBuffer* buffer)
+ : mPath(path)
+ , mDst(buffer)
+ {
+ }
+
+ IOTask::~IOTask()
+ {
+ }
+
+ bool IOTask::Execute()
+ {
+ return true;
+ }
+
+ void IOTask::Invoke()
+ {
+
+ }
+
+ }
+}
diff --git a/source/libs/asura-lib-utils/io/io_task.h b/source/libs/asura-lib-utils/io/io_task.h
index b91a88c..aa5b38e 100644
--- a/source/libs/asura-lib-utils/io/io_task.h
+++ b/source/libs/asura-lib-utils/io/io_task.h
@@ -16,7 +16,7 @@ namespace AsuraEngine
///
/// ȡļ
///
- class IOTask
+ class IOTask ASURA_FINAL
: public AEScripting::Portable<IOTask>
, public AEThreading::ThreadTask
{
@@ -24,13 +24,21 @@ namespace AsuraEngine
LUAX_DECL_FACTORY(IOTask);
+ IOTask(const std::string& path, DataBuffer* buffer);
+ ~IOTask();
+
bool Execute() override ;
+ void Invoke() override;
private:
std::string mPath;
DataBuffer* mDst;
+ Luax::LuaxMemberRef mDstRef;
+
+ LUAX_DECL_METHOD(_New);
+
};
}
diff --git a/source/libs/asura-lib-utils/math/quaternion.cpp b/source/libs/asura-lib-utils/math/quaternion.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-utils/math/quaternion.cpp
diff --git a/source/libs/asura-lib-utils/math/quaternion.h b/source/libs/asura-lib-utils/math/quaternion.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/libs/asura-lib-utils/math/quaternion.h
diff --git a/source/libs/asura-lib-utils/threading/binding/_coroutine.cpp b/source/libs/asura-lib-utils/threading/binding/_coroutine.cpp
new file mode 100644
index 0000000..7f74cca
--- /dev/null
+++ b/source/libs/asura-lib-utils/threading/binding/_coroutine.cpp
@@ -0,0 +1,40 @@
+#include "../coroutine.h"
+
+using namespace std;
+
+namespace AsuraEngine
+{
+ namespace Threading
+ {
+
+ LUAX_REGISTRY(Coroutine)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "New", _New },
+ { "Run", _Run }
+ );
+ }
+
+ LUAX_POSTPROCESS(Coroutine)
+ {
+
+ }
+
+ // Coroutine.New()
+ LUAX_IMPL_METHOD(Coroutine, _New)
+ {
+ LUAX_STATE(L);
+
+ return 0;
+ }
+
+ // coroutine:Run()
+ LUAX_IMPL_METHOD(Coroutine, _Run)
+ {
+ LUAX_PREPARE(L, Coroutine);
+
+ return 0;
+ }
+
+ }
+}
diff --git a/source/libs/asura-lib-utils/threading/binding/_thread.cpp b/source/libs/asura-lib-utils/threading/binding/_thread.cpp
new file mode 100644
index 0000000..9f6d228
--- /dev/null
+++ b/source/libs/asura-lib-utils/threading/binding/_thread.cpp
@@ -0,0 +1,104 @@
+#include "../thread.h"
+
+using namespace std;
+
+namespace AsuraEngine
+{
+ namespace Threading
+ {
+
+ LUAX_REGISTRY(Thread)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "New", _New },
+ { "Start", _Start },
+ { "Join", _Join },
+ { "Kill", _Kill },
+ { "AddTask", _AddTask },
+ { "IsRunning", _IsRunning },
+ { "IsCurrent", _IsCurrent },
+ { "GetName", _GetName }
+ );
+ }
+
+ LUAX_POSTPROCESS(Thread)
+ {
+
+ }
+
+ // thread = Thread.New(name)
+ LUAX_IMPL_METHOD(Thread, _New)
+ {
+ LUAX_STATE(L);
+
+ cc8* name = state.GetValue<cc8*>(1, "");
+
+ Thread* thread = new Thread(name);
+ thread->PushLuaxUserdata(state);
+
+ return 1;
+ }
+
+ // thread:Start()
+ LUAX_IMPL_METHOD(Thread, _Start)
+ {
+ LUAX_PREPARE(L, Thread);
+ self->Start();
+ return 0;
+ }
+
+ // thread:Join()
+ LUAX_IMPL_METHOD(Thread, _Join)
+ {
+ LUAX_PREPARE(L, Thread);
+ self->Join();
+ return 0;
+ }
+
+ // thread:Kill()
+ LUAX_IMPL_METHOD(Thread, _Kill)
+ {
+ LUAX_PREPARE(L, Thread);
+ self->Kill();
+ return 0;
+ }
+
+ // successed = thread:AddTask(thread_task)
+ LUAX_IMPL_METHOD(Thread, _AddTask)
+ {
+ LUAX_PREPARE(L, Thread);
+
+ ThreadTask* task = state.GetUserdata<ThreadTask>(2);
+ self->AddTask(task);
+ self->LuaxRetain<ThreadTask>(state, task);
+ return 0;
+ }
+
+ // thread:IsRunning()
+ LUAX_IMPL_METHOD(Thread, _IsRunning)
+ {
+ LUAX_PREPARE(L, Thread);
+
+ state.Push(self->IsRunning());
+ return 0;
+ }
+
+ // thread:IsCurrent()
+ LUAX_IMPL_METHOD(Thread, _IsCurrent)
+ {
+ LUAX_PREPARE(L, Thread);
+
+ state.Push(self->IsCurrent());
+ return 0;
+ }
+
+ // thread:GetName()
+ LUAX_IMPL_METHOD(Thread, _GetName)
+ {
+ LUAX_PREPARE(L, Thread);
+
+ return 0;
+ }
+
+ }
+}
diff --git a/source/libs/asura-lib-utils/threading/coroutine.h b/source/libs/asura-lib-utils/threading/coroutine.h
index 1ac6b21..75d9a10 100644
--- a/source/libs/asura-lib-utils/threading/coroutine.h
+++ b/source/libs/asura-lib-utils/threading/coroutine.h
@@ -28,4 +28,6 @@ namespace AsuraEngine
}
}
+namespace AEThreading = AsuraEngine::Threading;
+
#endif \ No newline at end of file
diff --git a/source/libs/asura-lib-utils/threading/mutex.cpp b/source/libs/asura-lib-utils/threading/mutex.cpp
index e69de29..e0b6e1e 100644
--- a/source/libs/asura-lib-utils/threading/mutex.cpp
+++ b/source/libs/asura-lib-utils/threading/mutex.cpp
@@ -0,0 +1,81 @@
+#include <asura-lib-utils/exceptions/exception.h>
+
+#include "mutex.h"
+
+namespace AsuraEngine
+{
+ namespace Threading
+ {
+
+#define try_create_mutex(impl)\
+ if (!mImpl) \
+ { \
+ try \
+ { \
+ mImpl = new impl(); \
+ } \
+ catch (Exception& e) \
+ { \
+ mImpl = nullptr; \
+ } \
+ }
+
+ Mutex::Mutex()
+ : mImpl(nullptr)
+ {
+#if ASURA_THREAD_WIN32
+ try_create_mutex(MutexImplWin32);
+#endif
+ ASSERT(mImpl);
+ }
+
+ Mutex::~Mutex()
+ {
+ delete mImpl;
+ }
+
+ void Mutex::Lock()
+ {
+ ASSERT(mImpl);
+
+ mImpl->Lock();
+ }
+
+ void Mutex::Unlock()
+ {
+ ASSERT(mImpl);
+
+ mImpl->Unlock();
+ }
+
+#if ASURA_THREAD_WIN32
+ MutexImplWin32::MutexImplWin32()
+ {
+ //mHandle = ::CreateMutex(NULL, FALSE, NULL);
+ //if (!mHandle)
+ // throw Exception("Cant use win32 mutex.");
+ ::InitializeCriticalSection(&mMutex);
+ }
+
+ MutexImplWin32::~MutexImplWin32()
+ {
+ //::CloseHandle(mHandle);
+ //mHandle = NULL;
+ ::DeleteCriticalSection(&mMutex);
+ }
+
+ void MutexImplWin32::Lock()
+ {
+ //::WaitForSingleObject(mHandle, INFINITE);
+ ::EnterCriticalSection(&mMutex);
+ }
+
+ void MutexImplWin32::Unlock()
+ {
+ //::ReleaseMutex(mHandle);
+ ::LeaveCriticalSection(&mMutex);
+ }
+#endif // ASURA_THREAD_WIN32
+
+ }
+}
diff --git a/source/libs/asura-lib-utils/threading/mutex.h b/source/libs/asura-lib-utils/threading/mutex.h
index 893c6e5..5ed45ae 100644
--- a/source/libs/asura-lib-utils/threading/mutex.h
+++ b/source/libs/asura-lib-utils/threading/mutex.h
@@ -1,21 +1,105 @@
#ifndef __ASURA_MUTEX_H__
#define __ASURA_MUTEX_H__
+#include <asura-lib-utils/type.h>
+
+#include "../utils_config.h"
+
+#if ASURA_THREAD_WIN32
+ #include <windows.h>
+#endif
+
namespace AsuraEngine
{
namespace Threading
{
+ class MutexImpl;
+
class Mutex
{
public:
+ Mutex();
+ ~Mutex();
+
void Lock();
void Unlock();
+ private:
+
+ MutexImpl* mImpl;
+
+ };
+
+ class Lock
+ {
+ public:
+ Lock(Mutex& mutex)
+ : m(mutex)
+ {
+ m.Lock();
+ };
+ ~Lock()
+ {
+ m.Unlock();
+ }
+ private:
+ void* operator new(size_t);
+ Mutex& m;
+ };
+
+#define lock(mutex) Lock _asura_scoped_lock_0x0_(mutex)
+#define lock2(mutex) Lock _asura_scoped_lock_0x1_(mutex)
+#define lock3(mutex) Lock _asura_scoped_lock_0x2_(mutex)
+#define lock4(mutex) Lock _asura_scoped_lock_0x3_(mutex)
+#define lock5(mutex) Lock _asura_scoped_lock_0x4_(mutex)
+
+ ASURA_ABSTRACT class MutexImpl
+ {
+ public:
+
+ MutexImpl() {};
+ virtual ~MutexImpl() {};
+
+ virtual void Lock() = 0;
+ virtual void Unlock() = 0;
+
+ };
+
+#if ASURA_THREAD_WIN32
+
+ //https://blog.csdn.net/l799623787/article/details/18259949
+ class MutexImplWin32 ASURA_FINAL : public MutexImpl
+ {
+ public:
+
+ MutexImplWin32();
+ ~MutexImplWin32();
+
+ void Lock() override;
+ void Unlock() override;
+
+ private:
+
+ //HANDLE mHandle;
+ CRITICAL_SECTION mMutex;
+
};
+#endif // ASURA_THREAD_WIN32
+
+#if ASURA_THREAD_STD
+
+ class MutexImplSTD ASURA_FINAL : public MutexImpl
+ {
+ };
+
+#endif // ASURA_THREAD_STD
+
}
}
+namespace AEThreading = AsuraEngine::Threading;
+
#endif \ No newline at end of file
diff --git a/source/libs/asura-lib-utils/threading/thread.cpp b/source/libs/asura-lib-utils/threading/thread.cpp
index c77f3ab..d1b055d 100644
--- a/source/libs/asura-lib-utils/threading/thread.cpp
+++ b/source/libs/asura-lib-utils/threading/thread.cpp
@@ -1,13 +1,92 @@
#include "thread.h"
+#include "thread_impl_win32.h"
+#include "thread_impl_posix.h"
+#include "thread_impl_sdl.h"
+#include "thread_impl_std.h"
+
namespace AsuraEngine
{
namespace Threading
{
- bool Thread::Enqueue(ThreadTask* task)
+ Thread::Thread(const std::string& name)
+ : mName(name)
+ {
+ }
+
+ Thread::~Thread()
+ {
+ delete mImpl;
+ }
+
+#define try_start_thread(impl)\
+ if (!mImpl) \
+ { \
+ mImpl = new impl(); \
+ if (!mImpl->Start(this, stacksize)) \
+ { \
+ delete mImpl; \
+ mImpl = nullptr; \
+ } \
+ }
+
+ bool Thread::AddTask(ThreadTask* task)
+ {
+ mTaskQueue.push(task);
+ return true;
+ }
+
+ void Thread::Start(uint32 stacksize)
+ {
+#if ASURA_THREAD_WIN32
+ try_start_thread(ThreadImplWin32);
+#endif
+
+ assert(mImpl);
+ }
+
+ void Thread::Join()
+ {
+ assert(mImpl);
+ mImpl->Join();
+ }
+
+ void Thread::Kill()
+ {
+ assert(mImpl);
+ mImpl->Kill();
+ }
+
+ bool Thread::IsRunning()
+ {
+ assert(mImpl);
+ return mImpl->IsRunning();
+ }
+
+ bool Thread::IsCurrent()
+ {
+ assert(mImpl);
+ return mImpl->IsCurrent();
+ }
+
+ const std::string& Thread::GetName()
+ {
+ return mName;
+ }
+
+ void Thread::Execute()
{
+ while (!mTaskQueue.empty())
+ {
+ ThreadTask* task = mTaskQueue.front();
+ if (task->Execute())
+ task->Invoke();
+ mMutex.Lock();
+ mTaskQueue.pop();
+ mMutex.Unlock();
+ }
}
}
diff --git a/source/libs/asura-lib-utils/threading/thread.h b/source/libs/asura-lib-utils/threading/thread.h
index 0058144..24b549c 100644
--- a/source/libs/asura-lib-utils/threading/thread.h
+++ b/source/libs/asura-lib-utils/threading/thread.h
@@ -1,10 +1,13 @@
#ifndef __ASURA_THREAD_H__
#define __ASURA_THREAD_H__
+#include <string>
#include <queue>
+
#include <asura-lib-utils/scripting/portable.hpp>
#include "thread_task.h"
+#include "mutex.h"
namespace AsuraEngine
{
@@ -23,21 +26,55 @@ namespace AsuraEngine
LUAX_DECL_FACTORY(Thread);
- bool Enqueue(ThreadTask* task);
+ Thread(const std::string& name = "");
+ ~Thread();
+
+ bool AddTask(ThreadTask* task);
+
+ void Start(uint32 stacksize = 0);
+
+ ///
+ /// ǿֹ̡߳עҪnewdeleteִ֮TerminateThread򽫲ڼʹnewˡ
+ /// https://blog.csdn.net/anye3000/article/details/7470674
+ ///
+ void Kill();
+
+ ///
+ /// ̵߳ȴ߳̽żִС
+ ///
+ void Join();
+
+ bool IsRunning();
- void Run();
+ bool IsCurrent();
+
+ ///
+ /// ִС
+ ///
+ void Execute();
+
+ const std::string& GetName();
private:
+ LUAX_DECL_METHOD(_New);
+ LUAX_DECL_METHOD(_Start);
+ LUAX_DECL_METHOD(_Join);
+ LUAX_DECL_METHOD(_Kill);
+ LUAX_DECL_METHOD(_AddTask);
+ LUAX_DECL_METHOD(_IsRunning);
+ LUAX_DECL_METHOD(_IsCurrent);
+ LUAX_DECL_METHOD(_GetName);
+
///
- /// С
+ /// С
///
std::queue<ThreadTask*> mTaskQueue;
- ThreadImpl* mImpl;
+ Mutex mMutex;
- LUAX_DECL_METHOD(_Enqueue);
- LUAX_DECL_METHOD(_Run);
+ ThreadImpl* mImpl;
+ std::string mName;
};
@@ -51,6 +88,15 @@ namespace AsuraEngine
ASURA_ABSTRACT class ThreadImpl
{
public:
+ ThreadImpl() {};
+ virtual ~ThreadImpl() {};
+
+ virtual bool Start(Thread* thread, uint32 stacksize = 0) = 0;
+ virtual void Join() = 0;
+ virtual void Kill() = 0;
+
+ virtual bool IsRunning() = 0;
+ virtual bool IsCurrent() = 0;
};
diff --git a/source/libs/asura-lib-utils/threading/thread_impl_std.h b/source/libs/asura-lib-utils/threading/thread_impl_std.h
index e69de29..0e7d3da 100644
--- a/source/libs/asura-lib-utils/threading/thread_impl_std.h
+++ b/source/libs/asura-lib-utils/threading/thread_impl_std.h
@@ -0,0 +1,43 @@
+#ifndef __ASURA_THREAD_STD_H__
+#define __ASURA_THREAD_STD_H__
+
+#include "../utils_config.h"
+
+#if ASURA_THREAD_STD
+
+#include <windows.h>
+
+#include "thread.h"
+
+namespace AsuraEngine
+{
+ namespace Threading
+ {
+
+ ///
+ /// Threadstd::threadʵ֡
+ ///
+ class ThreadImplSTD : public ThreadImpl
+ {
+ public:
+
+ ThreadImplSTD();
+ ~ThreadImplSTD();
+
+ bool Start(Thread* thread, uint32 stacksize) override;
+ void Join() override;
+ void Kill() override;
+
+ bool IsRunning() override;
+ bool IsCurrent() override;
+
+ private:
+
+ };
+
+ }
+}
+
+#endif // #if ASURA_THREAD_STD
+
+#endif // __ASURA_THREAD_STD_H__ \ No newline at end of file
diff --git a/source/libs/asura-lib-utils/threading/thread_impl_win32.cpp b/source/libs/asura-lib-utils/threading/thread_impl_win32.cpp
index e69de29..fd1b066 100644
--- a/source/libs/asura-lib-utils/threading/thread_impl_win32.cpp
+++ b/source/libs/asura-lib-utils/threading/thread_impl_win32.cpp
@@ -0,0 +1,69 @@
+#include "thread_impl_win32.h"
+#include "thread.h"
+
+namespace AsuraEngine
+{
+ namespace Threading
+ {
+
+ static DWORD WINAPI _thread_win32_runner(LPVOID param)
+ {
+ Thread* thread = (Thread*)param;
+ thread->Execute();
+ return 0;
+ }
+
+ ThreadImplWin32::ThreadImplWin32()
+ {
+ }
+
+ ThreadImplWin32::~ThreadImplWin32()
+ {
+ if (!mHandle) return;
+ ::CloseHandle(mHandle);
+ mHandle = 0;
+ }
+
+ bool ThreadImplWin32::Start(Thread* thread, uint32 stacksize/*=0*/)
+ {
+ assert(!IsRunning());
+ mHandle = ::CreateThread(
+ NULL
+ , stacksize
+ , _thread_win32_runner
+ , thread
+ , 0 /*е*/
+ , NULL);
+
+ return mHandle;
+ }
+
+ void ThreadImplWin32::Join()
+ {
+ // ̵߳ȴ̷߳
+ ::WaitForSingleObject(mHandle, INFINITE);
+ }
+
+ void ThreadImplWin32::Kill()
+ {
+ ::TerminateThread(mHandle, FALSE);
+ }
+
+ bool ThreadImplWin32::IsRunning()
+ {
+ if (mHandle) {
+ DWORD exitCode = 0;
+ // https://blog.csdn.net/yuanmeng567/article/details/19485719
+ ::GetExitCodeThread(mHandle, &exitCode);
+ return exitCode == STILL_ACTIVE;
+ }
+ return false;
+ }
+
+ bool ThreadImplWin32::IsCurrent()
+ {
+ return mHandle == ::GetCurrentThread();
+ }
+
+ }
+} \ No newline at end of file
diff --git a/source/libs/asura-lib-utils/threading/thread_impl_win32.h b/source/libs/asura-lib-utils/threading/thread_impl_win32.h
index 3dd2a8e..361152f 100644
--- a/source/libs/asura-lib-utils/threading/thread_impl_win32.h
+++ b/source/libs/asura-lib-utils/threading/thread_impl_win32.h
@@ -6,6 +6,7 @@
#if ASURA_THREAD_WIN32
#include <windows.h>
+
#include "thread.h"
namespace AsuraEngine
@@ -20,6 +21,16 @@ namespace AsuraEngine
{
public:
+ ThreadImplWin32();
+ ~ThreadImplWin32();
+
+ bool Start(Thread* thread, uint32 stacksize) override;
+ void Join() override;
+
+ void Kill() override;
+
+ bool IsRunning() override;
+ bool IsCurrent() override;
private:
@@ -32,4 +43,4 @@ namespace AsuraEngine
#endif // #if ASURA_THREAD_WIN32
-#endif \ No newline at end of file
+#endif // __ASURA_THREAD_WIN32_H__ \ No newline at end of file
diff --git a/source/libs/asura-lib-utils/threading/thread_task.h b/source/libs/asura-lib-utils/threading/thread_task.h
index 35e159c..1ea0a1a 100644
--- a/source/libs/asura-lib-utils/threading/thread_task.h
+++ b/source/libs/asura-lib-utils/threading/thread_task.h
@@ -2,6 +2,7 @@
#define __ASURA_THRAD_TASK_H__
#include <asura-lib-utils/type.h>
+#include <asura-lib-utils/scripting/portable.hpp>
namespace AsuraEngine
{
@@ -11,12 +12,28 @@ namespace AsuraEngine
///
/// ϣһ̴߳񣬼̳TaskдExecute
///
- ASURA_ABSTRACT class ThreadTask
+ ASURA_ABSTRACT class ThreadTask
+ : virtual public AEScripting::NativeAccessor
{
public:
+ ThreadTask();
+ virtual ~ThreadTask();
+
+ ///
+ /// ִɺ󷵻trueûص
+ ///
virtual bool Execute() = 0;
+ ///
+ /// ûص
+ ///
+ virtual void Invoke() = 0;
+
+ protected:
+
+ Luax::LuaxMemberRef mCallback;
+
};
}
diff --git a/source/libs/asura-lib-utils/utils_config.h b/source/libs/asura-lib-utils/utils_config.h
index 836eb07..d5208d5 100644
--- a/source/libs/asura-lib-utils/utils_config.h
+++ b/source/libs/asura-lib-utils/utils_config.h
@@ -2,5 +2,6 @@
#define __ASURA_UTILS_CONFIG_H__
#define ASURA_THREAD_WIN32 1
+#define ASURA_THREAD_STD 1
#endif \ No newline at end of file