更改字符集

This commit is contained in:
EmsiaetKadosh
2025-03-06 16:49:23 +08:00
parent ae4372827f
commit 28a836ff5f
27 changed files with 405 additions and 1 deletions
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+5 -1
View File
@@ -10,7 +10,10 @@ set(CMAKE_WIN32_EXECUTABLE true)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(${PROJECT_NAME} -Wno-microsoft-string-literal-from-predefined) add_compile_options(${PROJECT_NAME} -Wno-microsoft-string-literal-from-predefined)
endif () endif ()
#add_compile_options(${PROJECT_NAME} /utf-8) if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
add_compile_options(/source-charset:utf-8)
add_compile_options(/execution-charset:utf-8)
endif ()
include(CTest) include(CTest)
enable_testing() enable_testing()
@@ -44,3 +47,4 @@ add_executable(${PROJECT_NAME}
set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack) include(CPack)
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+43
View File
@@ -0,0 +1,43 @@
//
// Created by EmsiaetKadosh on 25-3-4.
//
#pragma once
#include "utils.h"
class Task;
class TaskScheduler;
class Task final : public AnywhereEditable<Task> {
friend class TaskScheduler;
public:
Function<void(Task& self)> func;
explicit Task(const Function<void(Task& self)>& func) : func(func) {}
explicit Task(Function<void(Task& self)>&& func) : func(std::move(func)) {}
void schedulePop(const bool pop) noexcept { reserved[0] = pop; }
bool scheduledPop() const noexcept { return reserved[0]; }
int pop() noexcept override {
schedulePop(true);
Success();
}
};
class TaskScheduler {
public:
AnywhereEditableList<Task> tasks;
void runAll() {
for (Task& task : tasks) {
task.func(task);
if (task.scheduledPop()) tasks.pop(&task);
}
}
void pushCopy(Task& task) { tasks.pushCopy(&task); }
/* 必须是new Task,交付托管 */
void pushNewed(Task* task) { tasks.pushNewed(task); }
void pushThis(Task& task) { tasks.pushThis(&task); }
};
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
//
// Created by EmsiaetKadosh on 25-3-6.
//
#include "gc.h"
+142
View File
@@ -0,0 +1,142 @@
//
// Created by EmsiaetKadosh on 25-3-6.
//
#pragma once
#include "def.h"
struct IGarbage;
template <typename T>
class Garbage;
class GarbageCollector;
struct IGarbage {
private:
friend class GarbageCollector;
IGarbage* next = nullptr;
protected:
void* ptr;
explicit IGarbage(void* ptr) : ptr(ptr) {}
virtual ~IGarbage() = default;
virtual void collect() = 0;
virtual void deleteThis() = 0;
};
template <typename T>
class Garbage final : public IGarbage {
friend class GarbageCollector;
public:
explicit Garbage(T* ptr) : IGarbage(ptr) {}
void collect() override { delete static_cast<T*>(ptr); }
protected:
void deleteThis() override { delete this; }
};
class GarbageCollector {
IGarbage* submitted = nullptr;
IGarbage* submittedEnd = nullptr;
IGarbage* packed = nullptr;
IGarbage* packedEnd = nullptr;
IGarbage* processing = nullptr;
public:
GarbageCollector() = default;
GarbageCollector(const GarbageCollector&) = delete;
GarbageCollector(GarbageCollector&&) = delete;
GarbageCollector& operator=(const GarbageCollector&) = delete;
GarbageCollector& operator=(GarbageCollector&&) = delete;
~GarbageCollector() {
IGarbage* iter = processing;
while (processing) {
iter = processing->next;
processing->collect();
processing->deleteThis();
processing = iter;
}
while (packed) {
iter = packed->next;
packed->collect();
packed->deleteThis();
packed = iter;
}
while (submitted) {
iter = submitted->next;
submitted->collect();
submitted->deleteThis();
submitted = iter;
}
submittedEnd = nullptr;
}
/** 只能在gameThread调用 */
template <TypeName T>
void submit(T* ptr) noexcept(false) {
IGarbage* garbage = new Garbage<T>(ptr);
if (IGarbage* end = submittedEnd) { // 后续添加,可能存在线程竞争
while (end->next) end = end->next; // 理论上不会进入循环,但防止万一
end->next = garbage;
if (submitted) submittedEnd = garbage; // 参考pack()submitted会被先置空
std::atomic_thread_fence(std::memory_order_acquire);
if (!submitted) submittedEnd = nullptr; // 防止submittedEnd = garbage在pack()中置空后进行。此函数是同步的,所以可以这样操作。
}
else { // 添加首个,一定不会有线程竞争;或先前的已经pack
submitted = garbage;
submittedEnd = garbage;
}
}
/** 只能在renderThread调用 */
void pack() {
if (!submitted) return; // 提交链为空,不进行后续操作,防止竞争
std::atomic_thread_fence(std::memory_order_acquire);
IGarbage* submit = submitted;
IGarbage* submitEnd = submittedEnd;
submitted = nullptr; // 先把这个置为nullptr
std::atomic_thread_fence(std::memory_order_acquire);
submittedEnd = nullptr;
if (IGarbage* end = packedEnd) {
while (end->next) end = end->next; // 以防万一
end->next = submit;
if (packed) packedEnd = submitEnd;
std::atomic_thread_fence(std::memory_order_acquire);
if (!packed) packedEnd = nullptr;
}
else {
packed = submit;
packedEnd = submitEnd;
}
while (packedEnd->next) packedEnd = packedEnd->next;
}
/** 只能在gameThread调用 */
void collect() {
IGarbage* next = processing;
while (processing) {
next = processing->next;
processing->next = nullptr;
processing->collect();
processing->deleteThis();
processing = next;
}
if (!packed) return;
// 搬运packed且搬运期间的packed链必须必须完全固定
// 保证运行顺序
processing = packed;
packed = nullptr;
std::atomic_thread_fence(std::memory_order_acquire);
packedEnd = nullptr;
std::atomic_thread_fence(std::memory_order_acquire);
while (processing) {
next = processing->next;
processing->next = nullptr;
processing->collect();
processing->deleteThis();
processing = next;
}
}
};
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+210
View File
@@ -0,0 +1,210 @@
//
// Created by EmsiaetKadosh on 25-3-4.
//
#pragma once
template <typename T, typename L = void>
class AnywhereEditable;
template <typename T, typename L = void>
class AnywhereEditableList;
template <typename T, typename L = void>
class AnywhereIterator;
class AnywhereIteratorEnd;
/**
* 此处无法进行代码编译层面的直接约束
* @tparam T 满足T extends AnywhereEditable<T, L>
* @tparam L 满足L extends AnywhereEditableList<T, L>
*/
template <typename T, typename L>
class AnywhereEditable {
public:
using Lst = std::conditional_t<std::is_same_v<L, void>, AnywhereEditableList<T, L>, L>;
private:
friend class AnywhereIterator<T, L>;
friend class AnywhereEditableList<T, L>;
friend class AnywhereIteratorEnd;
friend L;
AnywhereEditable* prev = nullptr;
AnywhereEditable* next = nullptr;
AnywhereEditableList<T, L>* list = nullptr; // 指示自身属于某个列表
protected:
bool managedByList = false; // 指示是否在列表内管理内存,而非列表外管理内存
byte reserved[7]{}; // reserved[0]: Task::schedulePop
public:
AnywhereEditable() = default;
AnywhereEditable(const AnywhereEditable& other) {}
AnywhereEditable(AnywhereEditable&& other) noexcept : prev(other->prev), next(other->next), list(other->list) {
other->prev = nullptr;
other->next = nullptr;
other->list = nullptr;
}
virtual ~AnywhereEditable() {
if (list) {
managedByList = false;
auto lst = list;
list = nullptr;
lst->pop(static_cast<T*>(this));
Logger.warn(L"~AnywhereEditable() : 析构时没有清除list,导致了析构时pop");
}
}
int pushCopy(AnywhereEditableList<T, L>& list) noexcept;
int pushThis(AnywhereEditableList<T, L>& list) noexcept;
virtual int pop() noexcept;
AnywhereEditableList<T, L>* getContainer() const noexcept { return list; }
};
template <typename T, typename L>
class AnywhereIterator {
friend class AnywhereIteratorEnd;
AnywhereEditable<T, L>* current;
public:
explicit AnywhereIterator(AnywhereEditable<T, L>* current) : current(current) {}
AnywhereIterator(const AnywhereIterator& other) = default;
T& operator*() noexcept(false) {
if (current->next) return static_cast<T&>(*current);
throw RuntimeException(L"AnywhereIterator::operator*() : next is null, end of list");
}
T* operator->() noexcept(false) {
if (current->next) return &static_cast<T&>(*current);
throw RuntimeException(L"AnywhereIterator::operator*() : next is null, end of list");
}
bool operator!=(const AnywhereIterator& other) const noexcept { return current != other.current; }
bool operator==(const AnywhereIterator& other) const noexcept { return current == other.current; }
bool operator!=(const AnywhereIteratorEnd& other) const noexcept;
bool operator==(const AnywhereIteratorEnd& other) const noexcept;
AnywhereIterator& operator++() noexcept(false) {
if (current->next) current = current->next;
else throw InvalidOperationException(L"AnywhereIterator::operator++() : end of list");
return *this;
}
AnywhereIterator operator++(int) noexcept(false) {
if (current->next) {
AnywhereIterator ret = *this;
current = current->next;
return ret;
}
throw InvalidOperationException(L"AnywhereIterator::operator++() : end of list");
}
AnywhereIterator& operator--() noexcept(false) {
if (current->prev) current = current->prev;
else throw InvalidOperationException(L"AnywhereIterator::operator--() : begin of list");
return *this;
}
AnywhereIterator operator--(int) noexcept(false) {
if (current->prev) {
AnywhereIterator ret = *this;
current = current->prev;
return ret;
}
throw InvalidOperationException(L"AnywhereIterator::operator--() : begin of list");
}
};
class AnywhereIteratorEnd {
public:
AnywhereIteratorEnd() {}
AnywhereIteratorEnd(const AnywhereIteratorEnd& other) = delete;
AnywhereIteratorEnd(AnywhereIteratorEnd&& other) = delete;
template <typename T, typename L>
bool operator!=(const AnywhereIterator<T, L>& other) const noexcept { return other.current && other.current->next; }
template <typename T, typename L>
bool operator==(const AnywhereIterator<T, L>& other) const noexcept { return !operator!=(other); }
};
template <typename T, typename L>
class AnywhereEditableList {
protected:
AnywhereEditable<T, L> head;
AnywhereEditable<T, L> tail;
public:
AnywhereEditableList() {
head.next = &tail;
tail.prev = &head;
}
virtual ~AnywhereEditableList() { for (AnywhereIterator<T, L> it = begin(); it != end(); ++it) {} }
int pushCopy(T* value) noexcept;
int pushThis(T* value) noexcept;
int pushNewed(T* value) noexcept;
virtual int pop(T* value) noexcept;
AnywhereIterator<T, L> begin() noexcept { return AnywhereIterator<T, L>(head.next); }
AnywhereIteratorEnd end() noexcept { return AnywhereIteratorEnd(); }
AnywhereIterator<T, L> begin() const noexcept { return AnywhereIterator<T, L>(head.next); }
AnywhereIteratorEnd end() const noexcept { return AnywhereIteratorEnd(); }
AnywhereEditable<T, L>* front() const noexcept { return head.next == &tail ? nullptr : head.next; }
AnywhereEditable<T, L>* back() const noexcept { return tail.prev == &head ? nullptr : tail.prev; }
};
template <typename T, typename L>
int AnywhereEditable<T, L>::pushCopy(AnywhereEditableList<T, L>& list) noexcept { return list.pushCopy(static_cast<T*>(this)); }
template <typename T, typename L>
int AnywhereEditable<T, L>::pushThis(AnywhereEditableList<T, L>& list) noexcept { return list.pushThis(static_cast<T*>(this)); }
template <typename T, typename L>
int AnywhereEditable<T, L>::pop() noexcept { return list->pop(static_cast<T*>(this)); }
template <typename T, typename L>
bool AnywhereIterator<T, L>::operator!=(const AnywhereIteratorEnd& other) const noexcept { return other != *this; }
template <typename T, typename L>
bool AnywhereIterator<T, L>::operator==(const AnywhereIteratorEnd& other) const noexcept { return other == *this; }
template <typename T, typename L>
int AnywhereEditableList<T, L>::pushCopy(T* value) noexcept {
T* nv = new T(*value);
return pushNewed(nv);
}
template <typename T, typename L>
int AnywhereEditableList<T, L>::pushThis(T* value) noexcept {
if (value->list) {
Logger.error(L"AnywhereEditableList::pushThis() : value is already in a list");
Failed();
}
value->list = this;
tail.prev->next = value;
value->prev = tail.prev;
value->next = &tail;
tail.prev = value;
Success();
}
template <typename T, typename L>
int AnywhereEditableList<T, L>::pushNewed(T* value) noexcept {
const int ret = pushThis(value);
if (ret) delete value;
else value->managedByList = true;
return ret;
}
template <typename T, typename L>
int AnywhereEditableList<T, L>::pop(T* value) noexcept {
if (value->list != this) {
Logger.error(L"AnywhereEditableList::pop() : value is not in this list");
Failed();
}
value->list = nullptr;
value->next->prev = value->prev;
value->prev->next = value->next;
if (value->managedByList) delete value;
Success();
}
BIN
View File
Binary file not shown.