格式整理

This commit is contained in:
EmsiaetKadosh
2025-03-16 14:18:05 +08:00
parent a1d0f11032
commit c344588924
23 changed files with 467 additions and 257 deletions
+65
View File
@@ -0,0 +1,65 @@
Checks: >
*,
-altera-id-dependent-backward-branch,
-altera-struct-pack-align,
-altera-unroll-loops,
-boost-*,
-bugprone-easily-swappable-parameters,
-bugprone-forward-declaration-namespace,
-bugprone-unhandled-exception-at-new,
-cert-err58-cpp,
-cppcoreguidelines-avoid-*,
-cppcoreguidelines-init-variables,
-cppcoreguidelines-macro-usage,
-cppcoreguidelines-missing-std-forward,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-type-member-init,
-cppcoreguidelines-pro-type-reinterpret-cast,
-cppcoreguidelines-rvalue-reference-param-not-moved,
-cppcoreguidelines-virtual-class-destructor,
-fuchsia-default-arguments-*,
-fuchsia-overloaded-operator,
-fuchsia-statically-constructed-objects,
-fuchsia-trailing-return,
-google-build-using-namespace,
-google-default-arguments,
-google-explicit-constructor,
-google-runtime-int,
-hicpp-avoid-c-arrays,
-hicpp-member-init,
-hicpp-signed-bitwise,
-hicpp-use-auto,
-llvm-header-guard,
-llvm-include-order,
-llvmlibc-*,
-misc-include-cleaner,
-misc-misplaced-const,
-misc-unused-parameters,
-misc-use-internal-linkage,
-modernize-avoid-c-arrays,
-modernize-use-auto,
-modernize-use-designated-initializers,
-modernize-use-ranges,
-modernize-use-trailing-return-type,
-modernize-use-using,
-performance-avoid-endl,
-performance-enum-size,
-performance-no-int-to-ptr,
-readability-avoid-unconditional-preprocessor-if,
-readability-braces-around-statements,
-readability-convert-member-functions-to-static,
-readability-function-cognitive-complexity,
-readability-identifier-length,
-readability-implicit-bool-conversion,
-readability-isolate-declaration,
-readability-magic-numbers,
-readability-math-missing-parentheses,
-readability-redundant-member-init,
-readability-use-std-min-max,
-*-braces-around-statements,
-*-exception-escape,
-*-named-parameter,
-*-non-private-member-variables-in-classes,
-*-special-member-functions,
-*-uppercase-literal-suffix
+6 -6
View File
@@ -30,7 +30,7 @@ private:
bool doReverse = true; bool doReverse = true;
public: public:
Animation() noexcept {} Animation() noexcept = default;
Animation& allowPositiveSuper(const bool val = true) noexcept { Animation& allowPositiveSuper(const bool val = true) noexcept {
positiveSuperAllowed = val; positiveSuperAllowed = val;
@@ -42,12 +42,12 @@ public:
return *this; return *this;
} }
Animation& depends(Depend depend) noexcept { Animation& depends(const Depend depend) noexcept {
this->depend = depend; this->depend = depend;
return *this; return *this;
} }
Animation& features(Style style) noexcept { Animation& features(const Style style) noexcept {
this->style = style; this->style = style;
return *this; return *this;
} }
@@ -62,7 +62,7 @@ public:
return *this; return *this;
} }
Animation& setDuration(const unsigned int val) noexcept { Animation& setDuration(const int val) noexcept {
if (duration == 0) duration = 1; if (duration == 0) duration = 1;
duration = val; duration = val;
return *this; return *this;
@@ -70,11 +70,11 @@ public:
void reset() const noexcept { progress = 0; } void reset() const noexcept { progress = 0; }
double weight(double x) const noexcept { static double weight(double x) noexcept {
if (x <= 0.0) return 0.0; if (x <= 0.0) return 0.0;
if (x >= 1.0) return 1.0; if (x >= 1.0) return 1.0;
x *= 2; x *= 2;
return x < 1.0 ? pow(x, 5.0) * 0.5 : 1.0 + pow(x - 2.0, 5.0) * 0.5; return x < 1.0 ? pow(x, 5.0) * 0.5 : pow(x - 2.0, 5.0) * 0.5 + 1.0;
} }
double calculateNext() const noexcept { double calculateNext() const noexcept {
+6 -6
View File
@@ -57,18 +57,18 @@ static constexpr wchar Table16[17] = L"0123456789ABCDEF";
String ret; String ret;
if (fills >= 8 || value < static_cast<unsigned int>(1) << fills * 4) { if (fills >= 8 || value < static_cast<unsigned int>(1) << fills * 4) {
ret.assign(fills, L'0'); ret.assign(fills, L'0');
for (unsigned int i = fills - 1; i != 0 && value; --i) { for (unsigned int i = fills - 1; i && value; --i) {
ret[i] = Table16[value & 0xf]; ret[i] = Table16[value & 0xf];
value >>= 4; value >>= 4;
} }
} else { } else {
unsigned int i = 0; unsigned int i = 0;
while (i < 8) { while (i < 8) {
if ((value >> i) & 0xf) break; if (value >> i & 0xf) break;
++i; ++i;
} }
while (i < 8) { while (i < 8) {
ret.push_back(Table16[(value >> i) & 0xf]); ret.push_back(Table16[value >> i & 0xf]);
++i; ++i;
} }
if (ret.empty()) ret = L"0"; if (ret.empty()) ret = L"0";
@@ -86,18 +86,18 @@ static constexpr wchar Table16[17] = L"0123456789ABCDEF";
String ret; String ret;
if (fills >= 16 || value < static_cast<QWORD>(1) << fills * 4) { if (fills >= 16 || value < static_cast<QWORD>(1) << fills * 4) {
ret.assign(fills, L'0'); ret.assign(fills, L'0');
for (QWORD i = fills - 1; i != 0 && value; --i) { for (QWORD i = fills - 1; i && value; --i) {
ret[i] = Table16[value & 0xf]; ret[i] = Table16[value & 0xf];
value >>= 4; value >>= 4;
} }
} else { } else {
QWORD i = 0; QWORD i = 0;
while (i < 16) { while (i < 16) {
if ((value >> i) & 0xf) break; if (value >> i & 0xf) break;
++i; ++i;
} }
while (i < 16) { while (i < 16) {
ret.push_back(Table16[(value >> i) & 0xf]); ret.push_back(Table16[value >> i & 0xf]);
++i; ++i;
} }
if (ret.empty()) ret = L"0"; if (ret.empty()) ret = L"0";
+83 -9
View File
@@ -4,17 +4,88 @@
#pragma once #pragma once
class File { class File {
public: public:
std::wfstream file; String path{};
explicit File(const std::wstring& path) : file(path, std::ios::in | std::ios::out | std::ios::binary) {} std::wfstream file{};
int flags = std::ios::in | std::ios::out | std::ios::binary;
File(const String& path) : path(path) {}
File(const File&) = delete;
File(File&&) = delete;
~File() { if (file.is_open()) file.close(); } ~File() { if (file.is_open()) file.close(); }
File& operator=(const File&) = delete;
File& operator=(File&&) = delete;
File& open() {
if (file.is_open()) file.close();
file.open(path, flags);
return *this;
}
File& close() {
if (file.is_open()) file.close();
return *this;
}
File& clearContent() {
file.clear();
if (file.is_open()) file.close();
file.open(path, flags | std::ios::trunc);
return *this;
}
File& inputs(const bool value = true) {
if (value) flags |= std::ios::in;
else flags &= ~std::ios::in;
return *this;
}
File& outputs(const bool value = true) {
if (value) flags |= std::ios::out;
else flags &= ~std::ios::out;
return *this;
}
File& binary(const bool value = true) {
if (value) flags |= std::ios::binary;
else flags &= ~std::ios::binary;
return *this;
}
File& append(const bool value = true) {
if (value) flags |= std::ios::app;
else flags &= ~std::ios::app;
return *this;
}
File& truncate(const bool value = true) {
if (value) flags |= std::ios::trunc;
else flags &= ~std::ios::trunc;
return *this;
}
template <typename T>
File& operator<<(T&& value) {
if (file.is_open()) file << std::forward<T>(value);
return *this;
}
File& operator<<(decltype(std::endl<wchar, std::char_traits<wchar>>) value) {
if (file.is_open()) file << value;
return *this;
}
template <typename T>
File& operator>>(T&& value) {
if (file.is_open()) file >> std::forward<T>(value);
return *this;
}
}; };
class Data { class Data {
public: public:
enum class DataType : int { enum class DataType : unsigned char {
Integer, Double, String, Boolean, Null, List, Object Integer, Double, String, Boolean, Null, List, Object
}; };
@@ -34,9 +105,7 @@ class DataLoader {
while (!file.file.eof()) { while (!file.file.eof()) {
wchar c = file.file.get(); wchar c = file.file.get();
if (c == L'\"') Success(); if (c == L'\"') Success();
if (c == L'\\') { if (c == L'\\') { c = file.file.get(); }
c = file.file.get();
}
} }
errorInfo = L"Error: String never ends. EOF comes before a '\"'"; errorInfo = L"Error: String never ends. EOF comes before a '\"'";
Failed(); Failed();
@@ -45,7 +114,7 @@ class DataLoader {
int loadUntil(int& line, wchar at = 0) { int loadUntil(int& line, wchar at = 0) {
String name = {}; String name = {};
String val = {}; String val = {};
enum { identifier, eq, value, end } status = identifier; enum : unsigned char { identifier, eq, value, end } status = identifier;
while (!file.file.eof()) { while (!file.file.eof()) {
const wchar c = file.file.get(); const wchar c = file.file.get();
if (c == L'\n') ++line; if (c == L'\n') ++line;
@@ -72,12 +141,17 @@ class DataLoader {
public: public:
String errorInfo = {}; String errorInfo = {};
explicit DataLoader(const String& path) : file(path) {} DataLoader(const String& path) : file(path) {}
DataLoader(const DataLoader&) = delete; DataLoader(const DataLoader&) = delete;
DataLoader(DataLoader&&) = delete; DataLoader(DataLoader&&) = delete;
DataLoader& operator=(const DataLoader&) = delete;
DataLoader& operator=(DataLoader&&) = delete;
~DataLoader() = default;
int load() { int load() {
int line = 1; int line = 1;
return loadUntil(line); return loadUntil(line);
} }
}; };
inline File& [[carlbeks::releasedat]] MainLogFile = (new File(L"log.txt"))->binary().inputs().outputs().truncate().open().operator<<(L"initialize MainLogFile\n");
+10 -13
View File
@@ -9,10 +9,9 @@
#include "gc.h" #include "gc.h"
#include "Hud.h" #include "Hud.h"
#include "Task.h" #include "Task.h"
#include "utils.h"
#include "Window.h" #include "Window.h"
class Game final : public IRenderable { class Game final /* : public IRenderable, public ITickable */ {
friend void gameThread(); friend void gameThread();
WindowManager windows; WindowManager windows;
Hud hud = Hud(); // 8 Hud hud = Hud(); // 8
@@ -21,14 +20,16 @@ class Game final : public IRenderable {
QWORD currentTick = 0; // 8 QWORD currentTick = 0; // 8
public: public:
mutable GarbageCollector gc;
TaskScheduler tasks; // 8 TaskScheduler tasks; // 8
std::minstd_rand random; std::minstd_rand random;
explicit Game(); Game();
~Game() override; ~Game();
void render() const noexcept override { [[nodiscard]] QWORD getTick() const noexcept { return currentTick; }
int closeWindow(Window* const window) noexcept { return windows.pop(window); }
void render() const noexcept {
if (renderer.checkResizing()) return; if (renderer.checkResizing()) return;
renderer.gameStartRender(); renderer.gameStartRender();
caption->render(); caption->render();
@@ -46,7 +47,7 @@ public:
int setWindow(Window* window) noexcept { int setWindow(Window* window) noexcept {
if (window) { if (window) {
if (window->onOpen()) { if (window->onOpen()) {
for (auto i = windows.begin(); i != windows.end(); ++i) i->passEvent(MouseActionCode::MAC_LEAVE, 0, 0, 0); for (Window& i : windows) i.passEvent(MouseActionCode::MAC_LEAVE, 0, 0, 0);
windows.pushNewed(window); windows.pushNewed(window);
Success(); Success();
} }
@@ -59,15 +60,11 @@ public:
[[nodiscard]] FloatWindow& getFloatWindow() const noexcept { return *floatWindow; } [[nodiscard]] FloatWindow& getFloatWindow() const noexcept { return *floatWindow; }
[[nodiscard]] Window* getWindow() const noexcept { [[nodiscard]] Window* getWindow() const noexcept {
if (const auto back = windows.back()) return static_cast<Window*>(back); if (auto *const back = windows.back()) return dynamic_cast<Window*>(back);
Logger.error(L"Game::getWindow returns nullptr"); Logger.error(L"Game::getWindow returns nullptr");
return nullptr; return nullptr;
} }
[[nodiscard]] QWORD getTick() const noexcept { return currentTick; }
int closeWindow(Window* const window) noexcept { return windows.pop(window); }
void tick() noexcept { void tick() noexcept {
++currentTick; ++currentTick;
floatWindow->clear(); floatWindow->clear();
@@ -89,7 +86,7 @@ public:
void passEvent(const MouseActionCode action, const MouseButtonCode value, const int x, const int y) const noexcept { void passEvent(const MouseActionCode action, const MouseButtonCode value, const int x, const int y) const noexcept {
caption->passEvent(action, value, x, y); caption->passEvent(action, value, x, y);
if (const auto window = getWindow()) window->passEvent(action, value, x, y); if (Window* const window = getWindow()) window->passEvent(action, value, x, y);
floatWindow->passEvent(action, value, x, y); floatWindow->passEvent(action, value, x, y);
} }
}; };
+21 -21
View File
@@ -3,10 +3,11 @@
// //
#pragma once #pragma once
#include <ranges> #include <ranges>
#include "Chars.h"
#include "def.h" #include "def.h"
#include "Chars.h"
#include "InteractManager.h" #include "InteractManager.h"
class LiteralText; class LiteralText;
@@ -37,7 +38,7 @@ class RenderableString {
FontStyle style = 0; FontStyle style = 0;
FontID idFont = 0; FontID idFont = 0;
explicit StringConfig() = default; StringConfig() = default;
void reset() noexcept { void reset() noexcept {
idFont = 0; idFont = 0;
@@ -109,10 +110,10 @@ class RenderableString {
using ConstIterator = List<StringConfig>::const_iterator; using ConstIterator = List<StringConfig>::const_iterator;
public: public:
explicit RenderableString(const String& string): RenderableString(string.c_str(), string.length()) {} RenderableString(const String& string): RenderableString(string.c_str(), string.length()) {}
explicit RenderableString(String&& string) : RenderableString(string.c_str(), string.length()) {} RenderableString(String&& string) : RenderableString(string.c_str(), string.length()) {}
explicit RenderableString(const wchar* const string, const QWORD length = static_cast<QWORD>(-1)) { RenderableString(const wchar* const string, const QWORD length = static_cast<QWORD>(-1)) {
if (length == -1) parseAppend(string); if (length == -1) parseAppend(string);
else parseAppend(string, length); else parseAppend(string, length);
} }
@@ -171,8 +172,8 @@ public:
return *this; return *this;
} }
int getHeight() const noexcept; [[nodiscard]] int getHeight() const noexcept;
int getWidth(FontID defaultID = 1) const noexcept; [[nodiscard]] int getWidth(FontID defaultID = 0) const noexcept;
int getWidth(RenderConfig* renderConfigs, FontID defaultID) const noexcept; int getWidth(RenderConfig* renderConfigs, FontID defaultID) const noexcept;
private: private:
@@ -353,14 +354,13 @@ private:
} }
}; };
inline RenderableString operator""_renderable(const wchar* const text, const QWORD len) noexcept { return RenderableString(text); } inline RenderableString operator""_renderable(const wchar* const text, const QWORD) noexcept { return RenderableString(text); }
class Font { class Font {
public: public:
Function<void(int width, int height)> resize; Function<void(int width, int height)> resize;
private: private:
friend class ObjectHolder<Font>;
friend class FontManager; friend class FontManager;
friend class RenderableString; friend class RenderableString;
const String name; const String name;
@@ -374,9 +374,9 @@ private:
const FontID id; const FontID id;
bool adaptAllSize = false; bool adaptAllSize = false;
explicit Font(const FontID id, const String& name, const double heightModifier, const double yOffset, const long escapement, const long orientation, const bool adaptAllSize) : name{ name }, yOffset(yOffset), heightModifier(heightModifier), height(interactSettings.actual.fontHeight * heightModifier), escapement(escapement), orientation(orientation), yOffsetPx(yOffset * height), id(id), adaptAllSize(adaptAllSize) {} Font(const FontID id, const String& name, const double heightModifier, const double yOffset, const long escapement, const long orientation, const bool adaptAllSize) : name{ name }, yOffset(yOffset), heightModifier(heightModifier), height(static_cast<long>(interactSettings.actual.fontHeight * heightModifier)), escapement(escapement), orientation(orientation), yOffsetPx(static_cast<long>(yOffset * height)), id(id), adaptAllSize(adaptAllSize) {}
explicit Font(const FontID id, String&& name, const double heightModifier, const double yOffset, const long escapement, const long orientation, const bool adaptAllSize) : name{ std::move(name) }, yOffset(yOffset), heightModifier(heightModifier), height(interactSettings.actual.fontHeight * heightModifier), escapement(escapement), orientation(orientation), yOffsetPx(yOffset * height), id(id), adaptAllSize(adaptAllSize) {} Font(const FontID id, String&& name, const double heightModifier, const double yOffset, const long escapement, const long orientation, const bool adaptAllSize) : name{ std::move(name) }, yOffset(yOffset), heightModifier(heightModifier), height(static_cast<long>(interactSettings.actual.fontHeight * heightModifier)), escapement(escapement), orientation(orientation), yOffsetPx(static_cast<long>(yOffset * height)), id(id), adaptAllSize(adaptAllSize) {}
public: public:
Font(const Font&) = default; Font(const Font&) = default;
@@ -427,11 +427,11 @@ public:
class FontManager { class FontManager {
Map<FontID, Font> fonts; Map<FontID, Font> fonts;
Font *defaultFont, *captionFont; Font *defaultFont, *captionFont;
FontID assigned = 1; FontID assigned = 0;
using IterFonts = Map<FontID, Font>::const_iterator; using IterFonts = Map<FontID, Font>::const_iterator;
public: public:
explicit FontManager() { FontManager() {
captionFont = &newFont(L"Microsoft YaHei UI Light"); captionFont = &newFont(L"Microsoft YaHei UI Light");
defaultFont = &newFont(L"Microsoft YaHei UI Light"); defaultFont = &newFont(L"Microsoft YaHei UI Light");
captionFont->height = interactSettings.actual.captionHeight >> 1; captionFont->height = interactSettings.actual.captionHeight >> 1;
@@ -463,14 +463,14 @@ public:
return fonts.emplace(assigned, std::move(Font(assigned, std::move(name), heightModifier, yOffset, adaptAllSize, escapement, orientation))).first->second; return fonts.emplace(assigned, std::move(Font(assigned, std::move(name), heightModifier, yOffset, adaptAllSize, escapement, orientation))).first->second;
} }
Font& getDefault() const noexcept { return *defaultFont; } [[nodiscard]] Font& getDefault() const noexcept { return *defaultFont; }
void resize(const int width, const int height) { void resize(const int width, const int height) {
for (auto& font : fonts | std::views::values) for (auto& font : fonts | std::views::values)
if (font.resize) font.resize(width, height); if (font.resize) font.resize(width, height);
else { else {
font.height = interactSettings.actual.fontHeight * font.heightModifier; font.height = static_cast<long>(interactSettings.actual.fontHeight * font.heightModifier);
font.yOffsetPx = font.height * font.yOffset; font.yOffsetPx = static_cast<long>(font.height * font.yOffset);
font.clear(); font.clear();
} }
} }
@@ -487,8 +487,8 @@ typedef class LiteralText final : public IText {
mutable RenderableString renderableString; mutable RenderableString renderableString;
public: public:
explicit LiteralText(const String& string): string(string), renderableString(string) {} LiteralText(const String& string): string(string), renderableString(string) {}
explicit LiteralText(String&& string): string(std::move(string)), renderableString(this->string) {} LiteralText(String&& string): string(std::move(string)), renderableString(this->string) {}
const String& getText() const noexcept override { return string; } const String& getText() const noexcept override { return string; }
@@ -501,8 +501,8 @@ class TranslatableText final : public IText {
mutable QWORD langConfig = 0; mutable QWORD langConfig = 0;
public: public:
explicit TranslatableText(const String& id) : idSrc(id) {} TranslatableText(const String& id) : idSrc(id) {}
explicit TranslatableText(String&& id) : idSrc(std::move(id)) {} TranslatableText(String&& id) : idSrc(std::move(id)) {}
const String& getText() const noexcept override; const String& getText() const noexcept override;
const RenderableString& getRenderableString() const noexcept override; const RenderableString& getRenderableString() const noexcept override;
void refreshText() const noexcept; void refreshText() const noexcept;
@@ -524,7 +524,7 @@ class Translator {
using IterLang = List<Language>::const_iterator; using IterLang = List<Language>::const_iterator;
public: public:
explicit Translator() { langMap.insert(std::make_pair(String(L"zh-cn"), 1)); } Translator() { langMap.insert(std::make_pair(String(L"zh-cn"), 1)); }
void addLang(const String& lang) noexcept { langMap.insert(std::make_pair(lang, ++idLangMax)); } void addLang(const String& lang) noexcept { langMap.insert(std::make_pair(lang, ++idLangMax)); }
void addLang(String&& lang) noexcept { langMap.insert(std::make_pair(lang, ++idLangMax)); } void addLang(String&& lang) noexcept { langMap.insert(std::make_pair(lang, ++idLangMax)); }
void loadLang(); void loadLang();
+1 -1
View File
@@ -280,4 +280,4 @@ bool InteractManager::isInClientCaption() const noexcept { return mouseX > inter
KeyStatus& InteractManager::getKey(const KeyBinding& binding) noexcept { return keyStatus[binding.keyCode]; } KeyStatus& InteractManager::getKey(const KeyBinding& binding) noexcept { return keyStatus[binding.keyCode]; }
MouseButtonCode InteractManager::getMouseButtonCode() const noexcept { return (keyStatus[VK_LBUTTON].isPressed() ? static_cast<int>(MouseButtonCodeEnum::MBC_L_DOWN) : 0) | (keyStatus[VK_RBUTTON].isPressed() ? static_cast<int>(MouseButtonCodeEnum::MBC_R_DOWN) : 0) | (keyStatus[VK_MBUTTON].isPressed() ? static_cast<int>(MouseButtonCodeEnum::MBC_M_DOWN) : 0); } MouseButtonCode InteractManager::getMouseButtonCode() const noexcept { return (keyStatus[VK_LBUTTON].isPressed() ? static_cast<unsigned int>(MouseButtonCodeEnum::MBC_L_DOWN) : 0) | (keyStatus[VK_RBUTTON].isPressed() ? static_cast<int>(MouseButtonCodeEnum::MBC_R_DOWN) : 0) | (keyStatus[VK_MBUTTON].isPressed() ? static_cast<int>(MouseButtonCodeEnum::MBC_M_DOWN) : 0); }
+2 -2
View File
@@ -62,7 +62,7 @@ class InteractManager {
public: public:
void initialize() noexcept { trackMouseEvent.hwndTrack = MainWindowHandle; } void initialize() noexcept { trackMouseEvent.hwndTrack = MainWindowHandle; }
explicit InteractManager(); InteractManager();
void update(const int keyCode, const bool isPressed) noexcept { void update(const int keyCode, const bool isPressed) noexcept {
if (keyCode >= 256) return; if (keyCode >= 256) return;
@@ -100,7 +100,7 @@ public:
[[nodiscard]] bool isInClientCaption() const noexcept; [[nodiscard]] bool isInClientCaption() const noexcept;
[[nodiscard]] KeyStatus& getKey(const int keyCode) noexcept { return keyStatus[keyCode]; } [[nodiscard]] KeyStatus& getKey(const int keyCode) noexcept { return keyStatus[keyCode]; }
[[nodiscard]] KeyStatus& getKey(const KeyBinding& binding) noexcept; [[nodiscard]] KeyStatus& getKey(const KeyBinding& binding) noexcept;
[[nodiscard]] int getMouseButtonCode() const noexcept; [[nodiscard]] unsigned int /*MouseButtonCode*/ getMouseButtonCode() const noexcept;
int dealMouseWheel() noexcept { int dealMouseWheel() noexcept {
const int ret = mouseWheel; const int ret = mouseWheel;
+9 -11
View File
@@ -73,8 +73,8 @@ class Renderer final : public ITickable {
public: public:
byte windowSize = 0; // 1, Windows: SIZE_*** byte windowSize = 0; // 1, Windows: SIZE_***
byte reserved[5] {}; byte reserved[5]{};
Task resizeReloadBitmap { [this](Task& task) { Task resizeReloadBitmap{ [this](Task& task) {
Logger.info(L"Scheduled task: resize reload bitmap " + std::to_wstring(windowWidth) + L" * " + std::to_wstring(windowHeight)); Logger.info(L"Scheduled task: resize reload bitmap " + std::to_wstring(windowWidth) + L" * " + std::to_wstring(windowHeight));
if (!canvasBitmap) { if (!canvasBitmap) {
canvasBitmap = CreateCompatibleBitmap(MainDC, windowWidth, windowHeight); canvasBitmap = CreateCompatibleBitmap(MainDC, windowWidth, windowHeight);
@@ -86,7 +86,7 @@ public:
} }
if (canvasBitmap && assistBitmap) { if (canvasBitmap && assistBitmap) {
task.pop(); task.pop();
Logger.info(L"Successfully reload bitmap " + ptrtow(reinterpret_cast<QWORD>(static_cast<void*>(canvasBitmap))) + L" " + ptrtow(reinterpret_cast<QWORD>(static_cast<void*>(assistBitmap)))); Logger.info(L"Successfully reload bitmap " + ptrtow(reinterpret_cast<QWORD>(canvasBitmap)) + L" " + ptrtow(reinterpret_cast<QWORD>(assistBitmap)));
this->resizeEnd(); this->resizeEnd();
} }
Logger.print(task.reserved[0]); Logger.print(task.reserved[0]);
@@ -94,11 +94,10 @@ public:
private: private:
void gameStartRender() noexcept; void gameStartRender() noexcept;
void gameEndRender() noexcept; void gameEndRender() noexcept;
public: public:
explicit Renderer() { Logger.put(L"Renderer created"); } Renderer() { Logger.put(L"Renderer created"); }
~Renderer() override { ~Renderer() override {
Logger.put(L"Renderer destroyed"); Logger.put(L"Renderer destroyed");
@@ -128,7 +127,7 @@ public:
* @param argb ARGB式颜色 * @param argb ARGB式颜色
* @return int BGR式颜色 * @return int BGR式颜色
*/ */
[[nodiscard]] static unsigned int changeColorFormat(const unsigned int argb) { return ((argb << 16) & 0xff0000) | (argb & 0xff00) | ((argb >> 16) & 0xff); } [[nodiscard]] static unsigned int changeColorFormat(const unsigned int argb) { return argb << 16 & 0xff0000 | argb & 0xff00 | argb >> 16 & 0xff; }
void assertRendering() const noexcept(false) { if (!isRendering) throw InvalidOperationException(L"Operation should be done while rendering"); } void assertRendering() const noexcept(false) { if (!isRendering) throw InvalidOperationException(L"Operation should be done while rendering"); }
@@ -167,7 +166,7 @@ public:
.right = x + w, .right = x + w,
.bottom = y + h .bottom = y + h
}; };
HBRUSH clr = CreateSolidBrush(changeColorFormat(color)); const HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
FillRect(canvasDC, &rect, clr); FillRect(canvasDC, &rect, clr);
deleteObject(clr); deleteObject(clr);
} else { } else {
@@ -178,7 +177,7 @@ public:
.bottom = y + h > windowHeight ? windowHeight - y : h .bottom = y + h > windowHeight ? windowHeight - y : h
}; };
blendFunction.SourceConstantAlpha = color >> 24; blendFunction.SourceConstantAlpha = color >> 24;
HBRUSH clr = CreateSolidBrush(changeColorFormat(color)); const HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
FillRect(assistDC, &rect, clr); FillRect(assistDC, &rect, clr);
deleteObject(clr); deleteObject(clr);
if (!AlphaBlend(canvasDC, x, y, rect.right, rect.bottom, assistDC, 0, 0, rect.right, rect.bottom, blendFunction)) Logger.error(L"AlphaBlend failed"); if (!AlphaBlend(canvasDC, x, y, rect.right, rect.bottom, assistDC, 0, 0, rect.right, rect.bottom, blendFunction)) Logger.error(L"AlphaBlend failed");
@@ -189,8 +188,7 @@ public:
assertRendering(); assertRendering();
//assertRenderThread(); //assertRenderThread();
if ((color & 0xff000000) == 0) return; if ((color & 0xff000000) == 0) return;
if ((color & 0xff000000) == 0xff000000) { if ((color & 0xff000000) == 0xff000000) { const HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
FillRect(canvasDC, rect, clr); FillRect(canvasDC, rect, clr);
deleteObject(clr); deleteObject(clr);
} else { } else {
@@ -201,7 +199,7 @@ public:
.bottom = rect->bottom > windowHeight ? windowHeight : rect->bottom - rect->top .bottom = rect->bottom > windowHeight ? windowHeight : rect->bottom - rect->top
}; };
blendFunction.SourceConstantAlpha = color >> 24; blendFunction.SourceConstantAlpha = color >> 24;
HBRUSH clr = CreateSolidBrush(changeColorFormat(color)); const HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
FillRect(assistDC, &r, clr); FillRect(assistDC, &r, clr);
deleteObject(clr); deleteObject(clr);
if (!AlphaBlend(canvasDC, rect->left, rect->top, r.right, r.bottom, assistDC, 0, 0, r.right, r.bottom, blendFunction)) Logger.error(L"AlphaBlend failed"); if (!AlphaBlend(canvasDC, rect->left, rect->top, r.right, r.bottom, assistDC, 0, 0, r.right, r.bottom, blendFunction)) Logger.error(L"AlphaBlend failed");
+12 -3
View File
@@ -10,12 +10,15 @@ class TaskScheduler;
class Task final : public AnywhereEditable<Task> { class Task final : public AnywhereEditable<Task> {
friend class TaskScheduler; friend class TaskScheduler;
#ifndef __CARLBEKS_DEBUG__
QWORD triggerInterval = 0, nextExecuteTime = 0, lastExecuteTime = 0;
#endif
public: public:
Function<void(Task& self)> func; Function<void(Task& self)> func;
explicit Task(const Function<void(Task& self)>& func) : func(func) {} Task(const Function<void(Task& self)>& func) : func(func) {}
explicit Task(Function<void(Task& self)>&& func) : func(std::move(func)) {} Task(Function<void(Task& self)>&& func) : func(std::move(func)) {}
void schedulePop(const bool pop) noexcept { reserved[0] = pop; } void schedulePop(const bool pop) noexcept { reserved[0] = pop; }
[[nodiscard]] bool scheduledPop() const noexcept { return reserved[0]; } [[nodiscard]] bool scheduledPop() const noexcept { return reserved[0]; }
@@ -23,6 +26,12 @@ public:
schedulePop(true); schedulePop(true);
Success(); Success();
} }
#ifndef __CARLBEKS_DEBUG__
Task& every(QWORD tick);
Task& after(QWORD tick);
Task& until(QWORD tick);
Task& forever();
#endif
}; };
class TaskScheduler { class TaskScheduler {
@@ -34,7 +43,7 @@ public:
task.func(task); task.func(task);
if (task.scheduledPop()) { if (task.scheduledPop()) {
task.schedulePop(false); task.schedulePop(false);
tasks.pop(&task); tasks.pop(&task); // pop后删除了内存,迭代器的current失效
} }
} }
} }
-15
View File
@@ -5,18 +5,3 @@
#pragma once #pragma once
inline void test() {} inline void test() {}
inline void rsa() {
int pk, sk;
int p = 0, q = 0; // = random prime;
int n = p * q;
int phi = (p - 1) * (q - 1);
int d = 0, e = 0;
// assert gcd(e, phi) == 1;
// assert d * e === 1 mod phi;
// encode:
int message = 0, package;
package = static_cast<int>(pow(message, e)) % n;
// decode:
message = static_cast<int>(pow(package, d)) % n;
}
+41 -37
View File
@@ -9,14 +9,14 @@
#include "InteractManager.h" #include "InteractManager.h"
int Window::pop() noexcept { int Window::pop() noexcept {
game.gc.submit(this); gc.submit(this);
Success(); Success();
} }
void Window::render() const noexcept { for (const ObjectHolder<Widget>& widget : widgets) widget->render(); } void Window::render() const noexcept { for (const Widget* widget : widgets) widget->render(); }
void Window::tick() noexcept { for (ObjectHolder<Widget>& widget : widgets) widget->tick(); } void Window::tick() noexcept { for (Widget* widget : widgets) widget->tick(); }
void Window::onResize() { for (ObjectHolder<Widget>& widget : widgets) widget->onResize(); } void Window::onResize() { for (Widget* widget : widgets) widget->onResize(); }
void Window::passEvent(const MouseActionCode action, const MouseButtonCode value, const int x, const int y) noexcept { for (ObjectHolder<Widget>& widget : widgets) widget->passEvent(action, value, x, y); } void Window::passEvent(const MouseActionCode action, const MouseButtonCode value, const int x, const int y) noexcept { for (Widget* widget : widgets) widget->passEvent(action, value, x, y); }
int WindowManager::pop(Window* value) noexcept { int WindowManager::pop(Window* value) noexcept {
if (value->list != static_cast<AnywhereEditableList*>(this)) { if (value->list != static_cast<AnywhereEditableList*>(this)) {
@@ -40,19 +40,20 @@ void WindowManager::clear() noexcept {
} }
CaptionWindow::CaptionWindow() { CaptionWindow::CaptionWindow() {
ObjectHolder<Widget>& close = widgets.emplace_back(Button(0, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::RIGHT_TOP, LiteralText(L"\\f\2\u2716"))); Widget* close = widgets.emplace_back(Button(0, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::RIGHT_TOP, LiteralText(L"\\f\1\u2716")));
close->mouseClick = [](Widget&, MouseButtonCode) { DestroyWindow(MainWindowHandle); };
close->onTick = [this](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(L"\\#ffee0000关闭窗口"_renderable); };
close->absolute(); close->absolute();
close->backgroundColor.hover = 0xffee0000; close->backgroundColor.hover = 0xffee0000;
close->backgroundColor.active = 0; close->backgroundColor.active = 0;
close->backgroundColor.inactive = 0xffaaaaaa; close->backgroundColor.inactive = 0xffaaaaaa;
close->backgroundColor.clicked = 0xffee8888; close->backgroundColor.clicked = 0xffee8888;
close->mouseDown = [](int) { DestroyWindow(MainWindowHandle); };
close->onTick = [&close, this](int) { if (close->containsMouse()) game.getFloatWindow().push(L"\\#ffee0000关闭窗口"_renderable); };
close->foregroundColor.hover = 0xff000000; close->foregroundColor.hover = 0xff000000;
close->foregroundColor.active = 0xff000000; close->foregroundColor.active = 0xff000000;
close->foregroundColor.inactive = 0xff000000; close->foregroundColor.inactive = 0xff000000;
close->foregroundColor.clicked = 0xff000000; close->foregroundColor.clicked = 0xff000000;
ObjectHolder<Widget>& minmax = widgets.emplace_back(Button(-interactSettings.actual.captionHeight, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::RIGHT_TOP, LiteralText(L"\\f\2🗖")));
Widget* minmax = widgets.emplace_back(Button(-interactSettings.actual.captionHeight, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::RIGHT_TOP, LiteralText(L"\\f\1🗖")));
minmax->absolute(); minmax->absolute();
minmax->backgroundColor.hover = 0xffcccccc; minmax->backgroundColor.hover = 0xffcccccc;
minmax->backgroundColor.active = 0; minmax->backgroundColor.active = 0;
@@ -62,7 +63,9 @@ CaptionWindow::CaptionWindow() {
minmax->foregroundColor.active = 0xff000000; minmax->foregroundColor.active = 0xff000000;
minmax->foregroundColor.inactive = 0xff000000; minmax->foregroundColor.inactive = 0xff000000;
minmax->foregroundColor.clicked = 0xff000000; minmax->foregroundColor.clicked = 0xff000000;
ObjectHolder<Widget>& hide = widgets.emplace_back(Button(-2 * interactSettings.actual.captionHeight, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::RIGHT_TOP, LiteralText(L"🗕")));
Widget* hide = widgets.emplace_back(Button(-2 * interactSettings.actual.captionHeight, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::RIGHT_TOP, LiteralText(L"\\f\1🗕")));
hide->mouseClick = [](Widget&, MouseButtonCode) { ShowWindow(MainWindowHandle, SW_MINIMIZE); };
hide->absolute(); hide->absolute();
hide->backgroundColor.hover = 0xffcccccc; hide->backgroundColor.hover = 0xffcccccc;
hide->backgroundColor.active = 0; hide->backgroundColor.active = 0;
@@ -72,7 +75,15 @@ CaptionWindow::CaptionWindow() {
hide->foregroundColor.active = 0xff000000; hide->foregroundColor.active = 0xff000000;
hide->foregroundColor.inactive = 0xff000000; hide->foregroundColor.inactive = 0xff000000;
hide->foregroundColor.clicked = 0xff000000; hide->foregroundColor.clicked = 0xff000000;
ObjectHolder<Widget>& options = widgets.emplace_back(Button(0, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::LEFT_TOP, LiteralText(L"\\f\2")));
Widget* options = widgets.emplace_back(Button(0, 0, interactSettings.actual.captionHeight, interactSettings.actual.captionHeight, Location::LEFT_TOP, LiteralText(L"\\f\1")));
options->onTick = [](const Widget& self, MouseButtonCode) {
if (self.containsMouse()) {
game.getFloatWindow().push(L"\\#ff4488aa设置"_renderable);
game.getFloatWindow().push(L"\\.ff4488aa\\#ff000000右键以刷新窗口绘制"_renderable);
}
};
options->mouseClick = [](Widget&, const MouseButtonCode code) { if (static_cast<int>(MouseButtonCodeEnum::MBC_R_DOWN) & code) { game.tasks.pushThis(renderer.resizeReloadBitmap); } };
options->absolute(); options->absolute();
options->backgroundColor.hover = 0xffcccccc; options->backgroundColor.hover = 0xffcccccc;
options->backgroundColor.active = 0; options->backgroundColor.active = 0;
@@ -82,13 +93,6 @@ CaptionWindow::CaptionWindow() {
options->foregroundColor.active = 0xff000000; options->foregroundColor.active = 0xff000000;
options->foregroundColor.inactive = 0xff000000; options->foregroundColor.inactive = 0xff000000;
options->foregroundColor.clicked = 0xff000000; options->foregroundColor.clicked = 0xff000000;
options->onTick = [options](int) {
if (options->containsMouse()) {
game.getFloatWindow().push(L"\\#ff4488aa设置"_renderable);
game.getFloatWindow().push(L"\\#ff4488aa右键以刷新窗口绘制"_renderable);
}
};
options->mouseDown = [](int code) { if (static_cast<int>(MouseButtonCodeEnum::MBC_R_DOWN) & code) { game.tasks.pushThis(renderer.resizeReloadBitmap); } };
} }
bool CaptionWindow::onOpen() { throw InvalidOperationException(L"Should not open CaptionWindow"); } bool CaptionWindow::onOpen() { throw InvalidOperationException(L"Should not open CaptionWindow"); }
@@ -96,12 +100,12 @@ void CaptionWindow::onClose() { throw InvalidOperationException(L"Should not clo
void CaptionWindow::render() const noexcept { void CaptionWindow::render() const noexcept {
renderer.fill(0, 0, renderer.getWidth(), interactSettings.actual.captionHeight, 0xff666666); renderer.fill(0, 0, renderer.getWidth(), interactSettings.actual.captionHeight, 0xff666666);
for (const ObjectHolder<Widget>& widget : widgets) widget->render(); for (const Widget* widget : widgets) widget->render();
} }
void CaptionWindow::onResize() { void CaptionWindow::onResize() {
int left = 0, right = 0; int left = 0, right = 0;
for (ObjectHolder<Widget>& widget : widgets) { for (Widget* widget : widgets) {
widget->w = interactSettings.actual.captionHeight; widget->w = interactSettings.actual.captionHeight;
widget->h = interactSettings.actual.captionHeight; widget->h = interactSettings.actual.captionHeight;
switch (widget->location) { switch (widget->location) {
@@ -132,7 +136,7 @@ void FloatWindow::render() const noexcept {
x = interactManager.getMouseX(); x = interactManager.getMouseX();
y = interactManager.getMouseY(); y = interactManager.getMouseY();
int height = 0, width = 0; int height = 0, width = 0;
for (const ObjectHolder<RenderableString>& str : strings.get()) { for (const RenderableString* str : strings.get()) {
height += str->getHeight(); height += str->getHeight();
if (str->getWidth() > width) width = str->getWidth(); if (str->getWidth() > width) width = str->getWidth();
} }
@@ -147,8 +151,8 @@ void FloatWindow::render() const noexcept {
const int xf = x + interactSettings.actual.floatWindowMargin; const int xf = x + interactSettings.actual.floatWindowMargin;
int yf = y + interactSettings.actual.floatWindowMargin; int yf = y + interactSettings.actual.floatWindowMargin;
for (const ObjectHolder<RenderableString>& str : strings.get()) { for (const RenderableString* str : strings.get()) {
fontManager.get(1).draw(*str, xf, yf); fontManager.getDefault().draw(*str, xf, yf);
yf += str->getHeight(); yf += str->getHeight();
} }
@@ -159,7 +163,7 @@ void FloatWindow::render() const noexcept {
unsigned int Widget::colorSelector(const Color& clr) const { unsigned int Widget::colorSelector(const Color& clr) const {
if (!isActive) return clr.inactive; if (!isActive) return clr.inactive;
if (!hasMouse) return clr.active; if (!hasMouse) return clr.active;
if (interactManager.getKey(VK_LBUTTON).isPressed() || interactManager.getKey(VK_RBUTTON).isPressed() || interactManager.getKey(VK_MBUTTON).isPressed()) return clr.clicked; if (hasMouseTrigger && (interactManager.getKey(VK_LBUTTON).isPressed() || interactManager.getKey(VK_RBUTTON).isPressed() || interactManager.getKey(VK_MBUTTON).isPressed())) return clr.clicked;
return clr.hover; return clr.hover;
} }
@@ -208,24 +212,24 @@ void Widget::onResize() {
break; break;
} }
} else { } else {
width = renderer.getWidth() * w; width = static_cast<int>(renderer.getWidth() * w);
height = renderer.getHeight() * h; height = static_cast<int>(renderer.getHeight() * h);
switch (location) { switch (location) {
case Location::LEFT_TOP: case Location::LEFT_TOP:
left = renderer.getWidth() * x; left = static_cast<int>(renderer.getWidth() * x);
top = renderer.getHeight() * y; top = static_cast<int>(renderer.getHeight() * y);
break; break;
case Location::LEFT: case Location::LEFT:
left = renderer.getWidth() * x; left = static_cast<int>(renderer.getWidth() * x);
top = static_cast<int>(renderer.getHeight() * y) + (renderer.getHeight() - height >> 1); top = static_cast<int>(renderer.getHeight() * y) + (renderer.getHeight() - height >> 1);
break; break;
case Location::LEFT_BOTTOM: case Location::LEFT_BOTTOM:
left = renderer.getWidth() * x; left = static_cast<int>(renderer.getWidth() * x);
top = static_cast<int>(renderer.getHeight() * y) + renderer.getHeight() - height; top = static_cast<int>(renderer.getHeight() * y) + renderer.getHeight() - height;
break; break;
case Location::TOP: case Location::TOP:
left = static_cast<int>(renderer.getWidth() * x) + (renderer.getWidth() - width >> 1); left = static_cast<int>(renderer.getWidth() * x) + (renderer.getWidth() - width >> 1);
top = renderer.getHeight() * y; top = static_cast<int>(renderer.getHeight() * y);
break; break;
case Location::CENTER: case Location::CENTER:
left = static_cast<int>(renderer.getWidth() * x) + (renderer.getWidth() - width >> 1); left = static_cast<int>(renderer.getWidth() * x) + (renderer.getWidth() - width >> 1);
@@ -237,7 +241,7 @@ void Widget::onResize() {
break; break;
case Location::RIGHT_TOP: case Location::RIGHT_TOP:
left = static_cast<int>(renderer.getWidth() * x) + renderer.getWidth() - width; left = static_cast<int>(renderer.getWidth() * x) + renderer.getWidth() - width;
top = renderer.getHeight() * y; top = static_cast<int>(renderer.getHeight() * y);
break; break;
case Location::RIGHT: case Location::RIGHT:
left = static_cast<int>(renderer.getWidth() * x) + renderer.getWidth() - width; left = static_cast<int>(renderer.getWidth() * x) + renderer.getWidth() - width;
@@ -277,8 +281,8 @@ ConfirmWindow& ConfirmWindow::requireConfirm(const Function<void(Button&)>& func
confirm->w = 0.5; confirm->w = 0.5;
confirm->x = 0; confirm->x = 0;
} }
confirm->onTick = [this](int) { if (confirm->containsMouse()) confirm->backgroundColor.hover = confirm->animation.adaptsColor(0x99008800, 0x9900ff00); }; confirm->onTick = [](Widget& confirm, MouseButtonCode) { if (confirm.containsMouse()) confirm.backgroundColor.hover = static_cast<Button&>(confirm).animation.adaptsColor(0x99008800, 0x9900ff00); };
confirm->mouseLeave = [this](int) { confirm->animation.reset(); }; confirm->mouseLeave = [](Widget& confirm, MouseButtonCode) { static_cast<Button&>(confirm).animation.reset(); };
if (func) func(*confirm); if (func) func(*confirm);
confirm->onResize(); confirm->onResize();
return *this; return *this;
@@ -286,7 +290,7 @@ ConfirmWindow& ConfirmWindow::requireConfirm(const Function<void(Button&)>& func
ConfirmWindow& ConfirmWindow::requireCancel(const Function<void(Button&)>& func) { ConfirmWindow& ConfirmWindow::requireCancel(const Function<void(Button&)>& func) {
cancel = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.1, 0.4, 0.08, Location::CENTER, LiteralText(L"Cancel")))).ptr()); cancel = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.1, 0.4, 0.08, Location::CENTER, LiteralText(L"Cancel")))).ptr());
cancel->mouseUp = [this](int) { cancel->mouseClick = [this](Widget&, MouseButtonCode) {
game.tasks.pushNewed(allocatedFor(new Task([this](Task& self) { game.tasks.pushNewed(allocatedFor(new Task([this](Task& self) {
if (game.closeWindow(this)) this->onClose(); if (game.closeWindow(this)) this->onClose();
self.pop(); self.pop();
@@ -311,8 +315,8 @@ ConfirmWindow& ConfirmWindow::requireCancel(const Function<void(Button&)>& func)
cancel->x = 0.125; cancel->x = 0.125;
cancel->w = 0.5; cancel->w = 0.5;
} }
cancel->onTick = [this](int) { if (cancel->containsMouse()) cancel->backgroundColor.hover = cancel->animation.adaptsColor(0x99880000, 0x99ff0000); }; cancel->onTick = [](Widget& cancel, MouseButtonCode) { if (cancel.containsMouse()) cancel.backgroundColor.hover = static_cast<Button&>(cancel).animation.adaptsColor(0x99880000, 0x99ff0000); };
cancel->mouseLeave = [this](int) { cancel->animation.reset(); }; cancel->mouseLeave = [](Widget& cancel, int) { static_cast<Button&>(cancel).animation.reset(); };
if (func) func(*cancel); if (func) func(*cancel);
cancel->onResize(); cancel->onResize();
return *this; return *this;
+38 -25
View File
@@ -12,7 +12,7 @@
class WindowManager; class WindowManager;
enum class MouseActionCode : int { enum class MouseActionCode : unsigned int {
MAC_MOVE = 0, MAC_MOVE = 0,
MAC_HOVER = 1, MAC_HOVER = 1,
MAC_DOWN = 2, MAC_DOWN = 2,
@@ -21,7 +21,7 @@ enum class MouseActionCode : int {
MAC_LEAVE = 5 MAC_LEAVE = 5
}; };
enum class MouseButtonCodeEnum : int { enum class MouseButtonCodeEnum : unsigned int {
MBC_L_DOWN = 0x1, MBC_L_DOWN = 0x1,
MBC_R_DOWN = 0x2, MBC_R_DOWN = 0x2,
MBC_M_DOWN = 0x4, MBC_M_DOWN = 0x4,
@@ -33,20 +33,20 @@ enum class MouseButtonCodeEnum : int {
/** /**
* @see MouseButtonCodeEnum * @see MouseButtonCodeEnum
*/ */
using MouseButtonCode = int; using MouseButtonCode = unsigned int;
class Widget : public IRenderable, public ITickable { class Widget : public IRenderable, public ITickable {
protected: protected:
int left = 0, top = 0, width = 0, height = 0; int left = 0, top = 0, width = 0, height = 0;
public: public:
using Action = Function<void(int)>; using Action = Function<void(Widget&, MouseButtonCode)>;
double x, y, w, h; double x, y, w, h;
Action mouseHover; // 传入int为:0,鼠标移动;其余,鼠标在其上的长时间悬浮 Action mouseHover; // 传入int为:0,鼠标移动;其余,鼠标在其上的长时间悬浮
Action mouseDown; // 传入int表示变更按键。0左, 1中, 2右 Action mouseDown; // 传入int表示变更按键。0左, 1中, 2右
Action mouseUp; // 传入int表示变更按键。0左, 1中, 2右 Action mouseUp; // 传入int表示变更按键。0左, 1中, 2右
Action mouseLeave; // 传入int忽略 Action mouseLeave; // 传入int忽略
Action mouseClick; // 传入int表示变更按键。0x0左, 0x1中, 0x2右;0xf表示是否双击 Action mouseClick; // 传入int表示变更按键。0x0左, 0x1中, 0x2右;0x8表示是否双击
Action onTick; // 传入int忽略 Action onTick; // 传入int忽略
Color backgroundColor; Color backgroundColor;
Color foregroundColor{ TextColor }; Color foregroundColor{ TextColor };
@@ -54,6 +54,7 @@ public:
protected: protected:
mutable bool hasMouse = false; mutable bool hasMouse = false;
mutable bool isActive = true; mutable bool isActive = true;
mutable bool hasMouseTrigger = false;
bool isAbsoluteLocation = false; bool isAbsoluteLocation = false;
public: public:
@@ -61,10 +62,10 @@ public:
Location textLocation = Location::CENTER; // 多余字节预声明备用 Location textLocation = Location::CENTER; // 多余字节预声明备用
protected: protected:
char unused[3]{}; char unused[2]{};
public: public:
explicit Widget(const double x, const double y, const double w, const double h, const Location location) : x(x), y(y), w(w), h(h), location(location) {} Widget(const double x, const double y, const double w, const double h, const Location location) : x(x), y(y), w(w), h(h), location(location) {}
unsigned int colorSelector(const Color& clr) const; unsigned int colorSelector(const Color& clr) const;
void render() const noexcept override; void render() const noexcept override;
@@ -95,12 +96,25 @@ public:
} }
virtual void onResize(); virtual void onResize();
virtual void onHover(const int value) noexcept { if (mouseHover) mouseHover(value); } virtual void onHover(const int value) noexcept { if (mouseHover) mouseHover(*this, value); }
virtual void onMouseDown(const MouseButtonCode code) noexcept { if (mouseDown) mouseDown(code); }
virtual void onMouseUp(const MouseButtonCode code) noexcept { if (mouseUp) mouseUp(code); } virtual void onMouseDown(const MouseButtonCode code) noexcept {
virtual void onMouseLeave(const int value) noexcept { if (mouseLeave) mouseLeave(value); } hasMouseTrigger = true;
virtual void onMouseClick(const int value) noexcept { if (mouseClick) mouseClick(value); } if (mouseDown) mouseDown(*this, code);
void tick() noexcept override { if (onTick) onTick(0); } }
virtual void onMouseUp(const MouseButtonCode code) noexcept {
if (mouseUp) mouseUp(*this, code);
if (hasMouseTrigger) onMouseClick(code);
}
virtual void onMouseLeave(const MouseButtonCode value) noexcept {
hasMouseTrigger = false;
if (mouseLeave) mouseLeave(*this, value);
}
virtual void onMouseClick(const MouseButtonCode value) noexcept { if (mouseClick) mouseClick(*this, value); }
void tick() noexcept override { if (onTick) onTick(*this, 0); }
virtual void passEvent(const MouseActionCode action, const MouseButtonCode value, const int x, const int y) noexcept { virtual void passEvent(const MouseActionCode action, const MouseButtonCode value, const int x, const int y) noexcept {
if (action == MouseActionCode::MAC_LEAVE || !isMouseIn(x, y)) { if (action == MouseActionCode::MAC_LEAVE || !isMouseIn(x, y)) {
@@ -123,7 +137,7 @@ public:
onMouseUp(value); onMouseUp(value);
break; break;
case MouseActionCode::MAC_DOUBLE: case MouseActionCode::MAC_DOUBLE:
onMouseClick(1); onMouseClick(0x80);
break; break;
default: default:
break; break;
@@ -139,7 +153,7 @@ protected:
Window() = default; Window() = default;
~Window() override {} ~Window() override = default;
public: public:
int pop() noexcept override; int pop() noexcept override;
@@ -164,7 +178,7 @@ public:
class WindowManager final : public AnywhereEditableList<Window, WindowManager>, public IRenderable, public ITickable { class WindowManager final : public AnywhereEditableList<Window, WindowManager>, public IRenderable, public ITickable {
public: public:
void render() const noexcept override { for (Window& i : *this) i.render(); } void render() const noexcept override { for (const Window& i : *this) i.render(); }
void tick() noexcept override { for (Window& i : *this) i.tick(); } void tick() noexcept override { for (Window& i : *this) i.tick(); }
int pop(Window* value) noexcept override; int pop(Window* value) noexcept override;
void clear() noexcept; void clear() noexcept;
@@ -173,7 +187,7 @@ public:
class CaptionWindow final : public Window { class CaptionWindow final : public Window {
public: public:
explicit CaptionWindow(); CaptionWindow();
bool onOpen() override; bool onOpen() override;
void onClose() override; void onClose() override;
void render() const noexcept override; void render() const noexcept override;
@@ -184,10 +198,10 @@ class FloatWindow final : public Window {
mutable int x = 0; // 标记渲染起始点 mutable int x = 0; // 标记渲染起始点
mutable int y = 0; // 标记渲染起始点 mutable int y = 0; // 标记渲染起始点
typedef List<ObjectHolder<RenderableString>> lt; typedef List<ObjectHolder<RenderableString>> lt;
SynchronizedHolder<lt> strings{}; SynchronizedHolder<lt> strings;
public: public:
explicit FloatWindow() : Window() { FloatWindow() : Window() {
strings.setNew<lt>(std::move(lt())); strings.setNew<lt>(std::move(lt()));
strings.ok(); strings.ok();
strings.async(); strings.async();
@@ -208,8 +222,8 @@ class Button : public Widget {
public: public:
ObjectHolder<IText> name; ObjectHolder<IText> name;
Animation animation = Animation().features(Animation::AS_CUBIC).setDuration(20); Animation animation = Animation().features(Animation::AS_CUBIC).setDuration(20);
explicit Button(const double x, const double y, const double w, const double h, const Location location, const ObjectHolder<IText>& text) : Widget(x, y, w, h, location), name(text) {} Button(const double x, const double y, const double w, const double h, const Location location, const ObjectHolder<IText>& text) : Widget(x, y, w, h, location), name(text) {}
explicit Button(const double x, const double y, const double w, const double h, const Location location, ObjectHolder<IText>&& text) : Widget(x, y, w, h, location), name(std::move(text)) {} Button(const double x, const double y, const double w, const double h, const Location location, ObjectHolder<IText>&& text) : Widget(x, y, w, h, location), name(std::move(text)) {}
void render() const noexcept override; void render() const noexcept override;
}; };
@@ -222,12 +236,11 @@ public:
*cancel = nullptr; *cancel = nullptr;
private: private:
explicit ConfirmWindow(const ObjectHolder<IText>& text) : Window(), text(text) {} ConfirmWindow(const ObjectHolder<IText>& text) : Window(), text(text) {}
explicit ConfirmWindow(ObjectHolder<IText>&& text) : Window(), text(std::move(text)) {} ConfirmWindow(ObjectHolder<IText>&& text) : Window(), text(std::move(text)) {}
public: public:
~ConfirmWindow() override { /* 不需要delete,析构时Window会自动delete */ ~ConfirmWindow() override = default; // 不需要delete,析构时Window会自动delete
}
void render() const noexcept override { void render() const noexcept override {
int w, h; int w, h;
+4 -2
View File
@@ -6,6 +6,7 @@
#include "Chars.h" #include "Chars.h"
#include "exception.h" #include "exception.h"
#include "Game.h"
template<TypeName Base> template<NewCopyable T> requires std::is_base_of_v<Base, T> && TypeName<T> template<TypeName Base> template<NewCopyable T> requires std::is_base_of_v<Base, T> && TypeName<T>
void ObjectHolder<Base>::set(const T& value) { void ObjectHolder<Base>::set(const T& value) {
@@ -26,8 +27,9 @@ void ObjectHolder<Base>::set(T&& value) {
} }
void requireNonnull(const void* value) noexcept(false) { if (!value) throw NullPointerException(L"value is null"); } void requireNonnull(const void* value) noexcept(false) { if (!value) throw NullPointerException(L"value is null"); }
void checkAllocation(const void* value) noexcept(false) { if (!value) throw BadAllocationException(L"bad allocation"); }
void printAllocate(void* value, size_t size, const String& msg) { void printAllocate(void* value, const size_t size, const String& msg) {
const String str = L"alloc " + ptrtow(reinterpret_cast<QWORD>(value)) + L" " + std::to_wstring(size) + String(L"B ") + msg; const String str = L"alloc " + ptrtow(reinterpret_cast<QWORD>(value)) + L" " + std::to_wstring(size) + String(L"B ") + msg;
Logger.log(str); Logger.log(str);
#if __CARLBEKS_MEMORY__ > 2 #if __CARLBEKS_MEMORY__ > 2
@@ -35,7 +37,7 @@ void printAllocate(void* value, size_t size, const String& msg) {
#endif #endif
} }
void printDeallocate(void* value, size_t size, const String& msg) { void printDeallocate(void* value, const size_t size, const String& msg) {
const String str = L"dealloc " + ptrtow(reinterpret_cast<QWORD>(value)) + L" " + std::to_wstring(size) + String(L"B ") + msg; const String str = L"dealloc " + ptrtow(reinterpret_cast<QWORD>(value)) + L" " + std::to_wstring(size) + String(L"B ") + msg;
Logger.log(str); Logger.log(str);
#if __CARLBEKS_MEMORY__ > 2 #if __CARLBEKS_MEMORY__ > 2
+23 -17
View File
@@ -18,7 +18,7 @@
#include <atomic> #include <atomic>
#include <thread> #include <thread>
#include <fstream> #include <fstream>
#include <math.h> #include <cmath>
using wchar = wchar_t; using wchar = wchar_t;
using QWORD = unsigned long long int; using QWORD = unsigned long long int;
@@ -31,7 +31,10 @@ template<typename F> using Function = std::function<F>;
#define Success() { return 0; } #define Success() { return 0; }
#define Failed() { return 1; } #define Failed() { return 1; }
#define Error() { return -1; } #define Error() { return -1; }
#define Comment(PARAMS) /##/ PARAMS
#define SameAs(PARAMS) Comment(PARAMS)
//NOLINTNEXTLINE(*-reserved-identifier)
#define _WINSOCKAPI_ /* 防止winsock.h被引入。winsock.h和winsock2.h冲突。 */ #define _WINSOCKAPI_ /* 防止winsock.h被引入。winsock.h和winsock2.h冲突。 */
#if false #if false
#include <WinSock2.h> #include <WinSock2.h>
@@ -45,7 +48,6 @@ template<typename F> using Function = std::function<F>;
#include <wingdi.h> #include <wingdi.h>
#include <WinUser.h> #include <WinUser.h>
#include <Uxtheme.h> #include <Uxtheme.h>
#include <iostream>
#include <dwmapi.h> #include <dwmapi.h>
#define WM_APP_LBUTTONUP (WM_APP + 1) #define WM_APP_LBUTTONUP (WM_APP + 1)
@@ -76,18 +78,19 @@ concept PointerType = std::is_pointer_v<T>;
template<typename T> template<typename T>
concept TypeName = NonreferenceType<T> && NonpointerType<T>; concept TypeName = NonreferenceType<T> && NonpointerType<T>;
inline std::wfstream& MainLogFile = *new std::wfstream(L"log.txt", std::ios::out | std::ios::trunc);
struct MemoryManager { struct MemoryManager {
struct MemoryInfo { struct MemoryInfo {
std::size_t size;
const String msg; const String msg;
std::size_t size;
}; };
Map<void*, MemoryInfo> allocated; Map<void*, MemoryInfo> allocated {};
constexpr MemoryManager() noexcept = default;
} inline memoryManager; } inline memoryManager;
void requireNonnull(const void* value) noexcept(false); void requireNonnull(const void* value) noexcept(false);
void checkAllocation(const void* value) noexcept(false);
inline String ptrtow(QWORD value); inline String ptrtow(QWORD value);
#if defined __CARLBEKS_DEBUG__ || defined __CARLBEKS_MEMORY__ #if defined __CARLBEKS_DEBUG__ || defined __CARLBEKS_MEMORY__
@@ -95,16 +98,16 @@ void printAllocate(void* value, std::size_t size, const String&);
void printDeallocate(void* value, std::size_t size, const String&); void printDeallocate(void* value, std::size_t size, const String&);
extern String atow(const char* chars); extern String atow(const char* chars);
template<typename T> T* _allocatedFor(T* value, const String& msg = L"", std::size_t size = sizeof(T)) { template<typename T> T* allocatedFor$(T* value, const String& msg = L"", std::size_t size = sizeof(T)) {
requireNonnull(value); requireNonnull(value);
const auto& k = memoryManager.allocated.emplace(value, MemoryManager::MemoryInfo{ size, L"[" + atow(typeid(T).name()) + L"] " + msg }).first; const auto& k = memoryManager.allocated.emplace(value, MemoryManager::MemoryInfo{ L"[" + atow(typeid(T).name()) + L"] " + msg , size}).first;
#if __CARLBEKS_MEMORY__ > 1 #if __CARLBEKS_MEMORY__ > 1
printAllocate(value, k->second.size, k->second.msg); printAllocate(value, k->second.size, k->second.msg);
#endif #endif
return value; return value;
} }
template<typename T> T* _deallocating(T* value) { template<typename T> T* deallocating$(T* value) {
#if __CARLBEKS_MEMORY__ > 1 #if __CARLBEKS_MEMORY__ > 1
const MemoryManager::MemoryInfo* info = nullptr; const MemoryManager::MemoryInfo* info = nullptr;
if (memoryManager.allocated.contains(value)) info = &memoryManager.allocated.at(value); if (memoryManager.allocated.contains(value)) info = &memoryManager.allocated.at(value);
@@ -115,11 +118,11 @@ template<typename T> T* _deallocating(T* value) {
} }
#if __CARLBEKS_MEMORY__ > 3 #if __CARLBEKS_MEMORY__ > 3
#define allocatedFor(val, ...) _allocatedFor(val, L"\n From " __FUNCSIG__ "\n At " __FILE__ ":" _STL_STRINGIZE(__LINE__) __VA_OPT__(,) __VA_ARGS__) #define allocatedFor(val, ...) allocatedFor$(val, L"\n From " __FUNCSIG__ "\n At " __FILE__ ":" _STL_STRINGIZE(__LINE__) __VA_OPT__(,) __VA_ARGS__)
#else #else
#define allocatedFor(val, ...) _allocatedFor(val, L"" __VA_OPT__(,) __VA_ARGS__) #define allocatedFor(val, ...) allocatedFor$(val, L"" __VA_OPT__(,) __VA_ARGS__)
#endif #endif
#define deallocating(val) _deallocating(val) #define deallocating(val) deallocating$(val)
#else #else
#define allocatedFor(val, ...) val #define allocatedFor(val, ...) val
#define deallocating(val) val #define deallocating(val) val
@@ -137,14 +140,11 @@ public:
*/ */
ObjectHolder() : value(nullptr), hasValue(false) {} ObjectHolder() : value(nullptr), hasValue(false) {}
// ReSharper disable once CppNonExplicitConvertingConstructor
ObjectHolder(Base* value) : value(value), hasValue(false) {} ObjectHolder(Base* value) : value(value), hasValue(false) {}
// ReSharper disable once CppNonExplicitConvertingConstructor
template<NewCopyable T> requires (std::is_base_of_v<Base, T> || std::is_same_v<Base, T>) && TypeName<T> template<NewCopyable T> requires (std::is_base_of_v<Base, T> || std::is_same_v<Base, T>) && TypeName<T>
ObjectHolder(const T& value) : value(allocatedFor(new T(value))), hasValue(true) {} ObjectHolder(const T& value) : value(allocatedFor(new T(value))), hasValue(true) {}
// ReSharper disable once CppNonExplicitConvertingConstructor
template<NewMoveable T> requires (std::is_base_of_v<Base, T> || std::is_same_v<Base, T>) && TypeName<T> template<NewMoveable T> requires (std::is_base_of_v<Base, T> || std::is_same_v<Base, T>) && TypeName<T>
ObjectHolder(T&& value) : value(allocatedFor(new T(std::forward<T>(value)))), hasValue(true) {} ObjectHolder(T&& value) : value(allocatedFor(new T(std::forward<T>(value)))), hasValue(true) {}
@@ -196,11 +196,17 @@ public:
return *value; return *value;
} }
// ReSharper disable once CppNonExplicitConversionOperator [[nodiscard]] operator Base*() const noexcept(false) { return value; }
Base* ptr() const noexcept { return value; } Base* ptr() const noexcept { return value; }
operator bool() const noexcept { return value; } operator bool() const noexcept { return value; }
bool operator!() const noexcept { return value == nullptr; } bool operator!() const noexcept { return value == nullptr; }
bool isManager() const noexcept { return hasValue; } [[nodiscard]] bool isManager() const noexcept { return hasValue; }
template<typename T> ObjectHolder<T> referenceof(const T& other) {
ObjectHolder ret{};
ret.value = &other;
return ret;
}
}; };
template<TypeName Base> class SynchronizedHolder { template<TypeName Base> class SynchronizedHolder {
+17 -9
View File
@@ -23,31 +23,39 @@ class NullPointerException final : public Exception {
inline static const String type = L"NullPointerException"; inline static const String type = L"NullPointerException";
public: public:
explicit NullPointerException(String&& msg) : Exception(std::move(msg), &type) {} NullPointerException(String&& msg) : Exception(std::move(msg), &type) {}
explicit NullPointerException(const String& msg) : Exception(msg, &type) {} NullPointerException(const String& msg) : Exception(msg, &type) {}
};
class BadAllocationException final : public Exception {
inline static const String type = L"BadAllocationException";
public:
BadAllocationException(String&& msg) : Exception(std::move(msg), &type) {}
BadAllocationException(const String& msg) : Exception(msg, &type) {}
}; };
class ArrayIndexOutOfBoundException final : public Exception { class ArrayIndexOutOfBoundException final : public Exception {
inline static const String type = L"ArrayIndexOutOfBoundException"; inline static const String type = L"ArrayIndexOutOfBoundException";
public: public:
explicit ArrayIndexOutOfBoundException(String&& msg) : Exception(std::move(msg), &type) {} ArrayIndexOutOfBoundException(String&& msg) : Exception(std::move(msg), &type) {}
explicit ArrayIndexOutOfBoundException(const String& msg) : Exception(msg, &type) {} ArrayIndexOutOfBoundException(const String& msg) : Exception(msg, &type) {}
}; };
class InvalidOperationException final : public Exception { class InvalidOperationException final : public Exception {
inline static const String type = L"InvalidOperationException"; inline static const String type = L"InvalidOperationException";
public: public:
explicit InvalidOperationException(String&& msg) : Exception(std::move(msg), &type) {} InvalidOperationException(String&& msg) : Exception(std::move(msg), &type) {}
explicit InvalidOperationException(const String& msg) : Exception(msg, &type) {} InvalidOperationException(const String& msg) : Exception(msg, &type) {}
}; };
class RuntimeException final : public Exception { class RuntimeException final : public Exception {
inline static const String type = L"RuntimeException"; inline static const String type = L"RuntimeException";
public: public:
explicit RuntimeException(String&& msg) : Exception(std::move(msg), &type) {} RuntimeException(String&& msg) : Exception(std::move(msg), &type) {}
explicit RuntimeException(const String& msg) : Exception(msg, &type) {} RuntimeException(const String& msg) : Exception(msg, &type) {}
}; };
@@ -68,7 +76,7 @@ class PublicLogger final {
public: public:
const String name; const String name;
explicit PublicLogger(const String& name): name(L" [" + name + L"] ") { std::wcout << L"PublicLogger created\n"; } PublicLogger(const String& name): name(L" [" + name + L"] ") { std::wcout << L"PublicLogger created\n"; }
PublicLogger& put(const String& msg) noexcept { PublicLogger& put(const String& msg) noexcept {
std::wcout << L"[] [Root]" + name + msg + L"\n"; std::wcout << L"[] [Root]" + name + msg + L"\n";
+18 -10
View File
@@ -4,7 +4,9 @@
#pragma once #pragma once
#include "warnings.h"
#include "def.h" #include "def.h"
#include "File.h"
struct IGarbage; struct IGarbage;
template <typename T> template <typename T>
@@ -18,7 +20,7 @@ private:
protected: protected:
void* ptr; void* ptr;
explicit IGarbage(void* ptr) : ptr(ptr) {} IGarbage(void* ptr) : ptr(ptr) {}
virtual ~IGarbage() = default; virtual ~IGarbage() = default;
virtual void collect() = 0; virtual void collect() = 0;
virtual void deleteThis() = 0; virtual void deleteThis() = 0;
@@ -29,7 +31,7 @@ class Garbage final : public IGarbage {
friend class GarbageCollector; friend class GarbageCollector;
public: public:
explicit Garbage(T* ptr) : IGarbage(ptr) {} Garbage(T* ptr) : IGarbage(ptr) {}
void collect() override { delete static_cast<T*>(deallocating(ptr)); } void collect() override { delete static_cast<T*>(deallocating(ptr)); }
protected: protected:
@@ -44,14 +46,14 @@ class GarbageCollector {
IGarbage* processing = nullptr; IGarbage* processing = nullptr;
public: public:
GarbageCollector() = default; GarbageCollector() { MainLogFile << L"initialize GarbageCollector" << std::endl; }
GarbageCollector(const GarbageCollector&) = delete; GarbageCollector(const GarbageCollector&) = delete;
GarbageCollector(GarbageCollector&&) = delete; GarbageCollector(GarbageCollector&&) = delete;
GarbageCollector& operator=(const GarbageCollector&) = delete; GarbageCollector& operator=(const GarbageCollector&) = delete;
GarbageCollector& operator=(GarbageCollector&&) = delete; GarbageCollector& operator=(GarbageCollector&&) = delete;
~GarbageCollector() { ~GarbageCollector() {
IGarbage* iter = processing; IGarbage* iter;
while (processing) { while (processing) {
iter = processing->next; iter = processing->next;
processing->collect(); processing->collect();
@@ -76,17 +78,21 @@ public:
/** 只能在gameThread调用 */ /** 只能在gameThread调用 */
template <TypeName T> template <TypeName T>
void submit(T* ptr) noexcept(false) { void submit(T* ptr) noexcept(false) {
IGarbage* garbage = allocatedFor(new Garbage<T>(ptr)); IGarbage* newedGarbage = allocatedFor(new Garbage<T>(ptr));
builtinSubmit(newedGarbage);
}
void builtinSubmit(IGarbage* const newedGarbage) noexcept(false) {
if (IGarbage* end = submittedEnd) { // 后续添加,可能存在线程竞争 if (IGarbage* end = submittedEnd) { // 后续添加,可能存在线程竞争
while (end->next) end = end->next; // 理论上不会进入循环,但防止万一 while (end->next) end = end->next; // 理论上不会进入循环,但防止万一
end->next = garbage; end->next = newedGarbage;
if (submitted) submittedEnd = garbage; // 参考pack()submitted会被先置空 if (submitted) submittedEnd = newedGarbage; // 参考pack()submitted会被先置空
std::atomic_thread_fence(std::memory_order_acquire); std::atomic_thread_fence(std::memory_order_acquire);
if (!submitted) submittedEnd = nullptr; // 防止submittedEnd = garbage在pack()中置空后进行。此函数是同步的,所以可以这样操作。 if (!submitted) submittedEnd = nullptr; // 防止submittedEnd = garbage在pack()中置空后进行。此函数是同步的,所以可以这样操作。
} }
else { // 添加首个,一定不会有线程竞争;或先前的已经pack else { // 添加首个,一定不会有线程竞争;或先前的已经pack
submitted = garbage; submitted = newedGarbage;
submittedEnd = garbage; submittedEnd = newedGarbage;
} }
} }
@@ -115,7 +121,7 @@ public:
/** 只能在gameThread调用 */ /** 只能在gameThread调用 */
void collect() { void collect() {
IGarbage* next = processing; IGarbage* next;
while (processing) { while (processing) {
next = processing->next; next = processing->next;
processing->next = nullptr; processing->next = nullptr;
@@ -140,3 +146,5 @@ public:
} }
} }
}; };
inline GarbageCollector& [[carlbeks::releasedat("main.cpp")]] gc = *new GarbageCollector();
+2 -2
View File
@@ -12,14 +12,14 @@ inline BOOL NewProcess(const String& cmdline) noexcept {
return CreateProcessW(nullptr, const_cast<wchar*>(cmdline.c_str()), nullptr, nullptr, 0, 0, nullptr, nullptr, &si, &pi); return CreateProcessW(nullptr, const_cast<wchar*>(cmdline.c_str()), nullptr, nullptr, 0, 0, nullptr, nullptr, &si, &pi);
} }
inline HRESULT RemoveDefaultCaption(HWND hWnd, const MARGINS* p) noexcept { return DwmExtendFrameIntoClientArea(hWnd, p); } inline HRESULT RemoveDefaultCaption(const HWND hWnd, const MARGINS* p) noexcept { return DwmExtendFrameIntoClientArea(hWnd, p); }
inline bool ShowConsoleIO() noexcept { inline bool ShowConsoleIO() noexcept {
AllocConsole(); AllocConsole();
FILE* pCout; FILE* pCout;
freopen_s(&pCout, "CONOUT$", "w", stdout); freopen_s(&pCout, "CONOUT$", "w", stdout);
FILE* pCin; FILE* pCin;
freopen_s(&pCin, "CONIN$", "r", stdin); freopen_s(&pCin, "CONOUT$", "r+", stdin);
return true; return true;
} }
+4 -2
View File
@@ -4,15 +4,17 @@
#pragma once #pragma once
#include "warnings.h"
#include "def.h" #include "def.h"
#include "File.h"
#include "exception.h" #include "exception.h"
#include "gc.h"
#include "utils.h" #include "utils.h"
#include "hbp.h" #include "hbp.h"
#include "Chars.h" #include "Chars.h"
#include "gc.h"
#include "Task.h" #include "Task.h"
#include "File.h"
#include "Renderer.h" #include "Renderer.h"
#include "Animation.h" #include "Animation.h"
#include "InteractManager.h" #include "InteractManager.h"
+53 -46
View File
@@ -3,7 +3,7 @@
#include "IText.h" #include "IText.h"
#include "TestCode.h" #include "TestCode.h"
LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT __stdcall WndProc(const HWND hwnd, const UINT uMsg, const WPARAM wParam, const LPARAM lParam) {
switch (uMsg) { switch (uMsg) {
[[likely]] [[likely]]
case WM_PAINT: { case WM_PAINT: {
@@ -68,7 +68,7 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
default: default:
break; break;
} }
renderer.windowSize = wParam; renderer.windowSize = static_cast<byte>(wParam);
break; break;
case WM_KEYDOWN: case WM_KEYDOWN:
interactManager.update(static_cast<int>(wParam), true); interactManager.update(static_cast<int>(wParam), true);
@@ -86,40 +86,40 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
case WM_NCLBUTTONDOWN: case WM_NCLBUTTONDOWN:
if (interactManager.isInClientCaption()) { if (interactManager.isInClientCaption()) {
interactManager.update(VK_LBUTTON, true); interactManager.update(VK_LBUTTON, true);
game.passEvent(MouseActionCode::MAC_DOWN, interactManager.getMouseButtonCode() | static_cast<int>(MouseButtonCodeEnum::MBC_L_CHANGE), interactManager.getMouseX(), interactManager.getMouseY()); game.passEvent(MouseActionCode::MAC_DOWN, interactManager.getMouseButtonCode() | static_cast<unsigned int>(MouseButtonCodeEnum::MBC_L_CHANGE), interactManager.getMouseX(), interactManager.getMouseY());
} }
break; break;
case WM_RBUTTONDOWN: case WM_RBUTTONDOWN:
case WM_NCRBUTTONDOWN: case WM_NCRBUTTONDOWN:
if (interactManager.isInClientCaption()) { if (interactManager.isInClientCaption()) {
interactManager.update(VK_RBUTTON, true); interactManager.update(VK_RBUTTON, true);
game.passEvent(MouseActionCode::MAC_DOWN, interactManager.getMouseButtonCode() | static_cast<int>(MouseButtonCodeEnum::MBC_R_CHANGE), interactManager.getMouseX(), interactManager.getMouseY()); game.passEvent(MouseActionCode::MAC_DOWN, interactManager.getMouseButtonCode() | static_cast<unsigned int>(MouseButtonCodeEnum::MBC_R_CHANGE), interactManager.getMouseX(), interactManager.getMouseY());
} }
break; break;
case WM_APP_LBUTTONUP: // case WM_LBUTTONUP: case WM_NCLBUTTONUP: case WM_APP_LBUTTONUP:
if (interactManager.isInClientCaption()) { if (interactManager.isInClientCaption()) {
interactManager.update(VK_LBUTTON, false); interactManager.update(VK_LBUTTON, false);
game.passEvent(MouseActionCode::MAC_UP, interactManager.getMouseButtonCode() | static_cast<int>(MouseButtonCodeEnum::MBC_L_CHANGE), interactManager.getMouseX(), interactManager.getMouseY()); game.passEvent(MouseActionCode::MAC_UP, interactManager.getMouseButtonCode() | static_cast<unsigned int>(MouseButtonCodeEnum::MBC_L_CHANGE), interactManager.getMouseX(), interactManager.getMouseY());
} }
break; break;
case WM_RBUTTONUP: case WM_RBUTTONUP:
case WM_NCRBUTTONUP: case WM_NCRBUTTONUP:
if (interactManager.isInClientCaption()) { if (interactManager.isInClientCaption()) {
interactManager.update(VK_RBUTTON, false); interactManager.update(VK_RBUTTON, false);
game.passEvent(MouseActionCode::MAC_UP, interactManager.getMouseButtonCode() | static_cast<int>(MouseButtonCodeEnum::MBC_R_CHANGE), interactManager.getMouseX(), interactManager.getMouseY()); game.passEvent(MouseActionCode::MAC_UP, interactManager.getMouseButtonCode() | static_cast<unsigned int>(MouseButtonCodeEnum::MBC_R_CHANGE), interactManager.getMouseX(), interactManager.getMouseY());
} }
break; break;
case WM_APP_MBUTTONDOWN: // case WM_MBUTTONDOWN: case WM_NCMBUTTONDOWN: case WM_APP_MBUTTONDOWN:
if (interactManager.isInClientCaption()) { if (interactManager.isInClientCaption()) {
if (wParam & 0x10) interactManager.update(VK_MBUTTON, true); if (static_cast<QWORD>(wParam) & 0x10u) interactManager.update(VK_MBUTTON, true);
game.passEvent(MouseActionCode::MAC_DOWN, interactManager.getMouseButtonCode() | static_cast<int>(MouseButtonCodeEnum::MBC_M_CHANGE), interactManager.getMouseX(), interactManager.getMouseY()); game.passEvent(MouseActionCode::MAC_DOWN, interactManager.getMouseButtonCode() | static_cast<unsigned int>(MouseButtonCodeEnum::MBC_M_CHANGE), interactManager.getMouseX(), interactManager.getMouseY());
} }
break; break;
case WM_MBUTTONUP: case WM_MBUTTONUP:
case WM_NCMBUTTONUP: case WM_NCMBUTTONUP:
if (interactManager.isInClientCaption()) { if (interactManager.isInClientCaption()) {
interactManager.update(VK_MBUTTON, false); interactManager.update(VK_MBUTTON, false);
game.passEvent(MouseActionCode::MAC_UP, interactManager.getMouseButtonCode() | static_cast<int>(MouseButtonCodeEnum::MBC_M_CHANGE), interactManager.getMouseX(), interactManager.getMouseY()); game.passEvent(MouseActionCode::MAC_UP, interactManager.getMouseButtonCode() | static_cast<unsigned int>(MouseButtonCodeEnum::MBC_M_CHANGE), interactManager.getMouseX(), interactManager.getMouseY());
} }
break; break;
case WM_MOUSEWHEEL: case WM_MOUSEWHEEL:
@@ -138,23 +138,22 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (!interactManager.isInWindow()) game.passEvent(MouseActionCode::MAC_LEAVE, 0, interactManager.getMouseX(), interactManager.getMouseY()); if (!interactManager.isInWindow()) game.passEvent(MouseActionCode::MAC_LEAVE, 0, interactManager.getMouseX(), interactManager.getMouseY());
break; break;
case WM_DWMCOMPOSITIONCHANGED: { case WM_DWMCOMPOSITIONCHANGED: {
MARGINS margins{ constexpr MARGINS margins{
.cxLeftWidth = 0, .cxLeftWidth = 0,
.cxRightWidth = 0, .cxRightWidth = 0,
.cyTopHeight = 0, .cyTopHeight = 0,
.cyBottomHeight = 0 .cyBottomHeight = 0
}; };
margins = { -1 };
RemoveDefaultCaption(hwnd, &margins); RemoveDefaultCaption(hwnd, &margins);
break; break;
} }
case WM_NCCALCSIZE: case WM_NCCALCSIZE:
if (wParam == 1) { if (wParam == 1) {
NCCALCSIZE_PARAMS* pncsp = reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam); NCCALCSIZE_PARAMS* params = reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam);
pncsp->rgrc[0].left = pncsp->rgrc[0].left + 0; params->rgrc[0].left = params->rgrc[0].left + 0;
pncsp->rgrc[0].top = pncsp->rgrc[0].top + 0; params->rgrc[0].top = params->rgrc[0].top + 0;
pncsp->rgrc[0].right = pncsp->rgrc[0].right - 0; params->rgrc[0].right = params->rgrc[0].right - 0;
pncsp->rgrc[0].bottom = pncsp->rgrc[0].bottom - 0; params->rgrc[0].bottom = params->rgrc[0].bottom - 0;
renderer.resizeStart(); renderer.resizeStart();
return 0; return 0;
} }
@@ -170,7 +169,7 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
return 0; return 0;
[[unlikely]] [[unlikely]]
case WM_CREATE: case WM_CREATE:
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER); // Force post NCCALCSIZE SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
renderer.resizeEnd(); renderer.resizeEnd();
break; break;
default: default:
@@ -179,7 +178,7 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
return DefWindowProcW(hwnd, uMsg, wParam, lParam); return DefWindowProcW(hwnd, uMsg, wParam, lParam);
} }
LRESULT __stdcall HookProc(int code, WPARAM wParam, LPARAM lParam) { LRESULT __stdcall HookProc(const int code, const WPARAM wParam, const LPARAM lParam) {
if (code < 0) { if (code < 0) {
Logger.log(L"HookProc nCode < 0"); Logger.log(L"HookProc nCode < 0");
return CallNextHookEx(nullptr, code, wParam, lParam); return CallNextHookEx(nullptr, code, wParam, lParam);
@@ -188,10 +187,12 @@ LRESULT __stdcall HookProc(int code, WPARAM wParam, LPARAM lParam) {
case WM_LBUTTONUP: case WM_LBUTTONUP:
case WM_NCLBUTTONUP: case WM_NCLBUTTONUP:
PostMessageW(MainWindowHandle, WM_APP_LBUTTONUP, p->wParam, p->lParam); PostMessageW(MainWindowHandle, WM_APP_LBUTTONUP, p->wParam, p->lParam);
MainLogFile << L"BUTTON-UP\n";
return 0; return 0;
case WM_MBUTTONDOWN: case WM_MBUTTONDOWN:
case WM_NCMBUTTONDOWN: case WM_NCMBUTTONDOWN:
PostMessageW(MainWindowHandle, WM_APP_MBUTTONDOWN, p->wParam, p->lParam); PostMessageW(MainWindowHandle, WM_APP_MBUTTONDOWN, p->wParam, p->lParam);
MainLogFile << L"BUTTON-DOWN\n";
return 0; return 0;
default: default:
break; break;
@@ -205,7 +206,7 @@ void gameThread() {
using Time = time_point<system_clock>; using Time = time_point<system_clock>;
Time lastTick = system_clock::now(); Time lastTick = system_clock::now();
while (isRunning) { while (isRunning) {
Time thisTime = system_clock::now(); const Time thisTime = system_clock::now();
if (thisTime - lastTick < milliseconds(45)) { if (thisTime - lastTick < milliseconds(45)) {
Sleep(1); Sleep(1);
continue; continue;
@@ -228,7 +229,7 @@ void renderThread() {
renderer.initialize(); renderer.initialize();
Time lastRender = system_clock::now(); Time lastRender = system_clock::now();
while (isRunning) { while (isRunning) {
Time thisTime = system_clock::now(); const Time thisTime = system_clock::now();
if (thisTime - lastRender < milliseconds(12)) { if (thisTime - lastRender < milliseconds(12)) {
Sleep(1); Sleep(1);
continue; continue;
@@ -243,7 +244,8 @@ void renderThread() {
DestroyWindow(MainWindowHandle); DestroyWindow(MainWindowHandle);
} }
int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { int __stdcall wWinMain(const HINSTANCE hInstance, const HINSTANCE, [[maybe_unused]] const LPWSTR lpCmdLine, [[maybe_unused]] const int nShowCmd) {
MainLogFile << L"wWinMain started" << std::endl;
game.setWindow(StartWindow::create()); // 次序提前至最先 game.setWindow(StartWindow::create()); // 次序提前至最先
for (const auto& [addr, info] : memoryManager.allocated) { Logger.print(L" using", addr, info.size, L"B", info.msg); } for (const auto& [addr, info] : memoryManager.allocated) { Logger.print(L" using", addr, info.size, L"B", info.msg); }
MainLogFile << L"--------Program Start--------" << std::endl; MainLogFile << L"--------Program Start--------" << std::endl;
@@ -257,60 +259,64 @@ int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCm
wc.hInstance = hInstance; wc.hInstance = hInstance;
wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION); wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
wc.hCursor = LoadCursor(nullptr, IDC_ARROW); wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); wc.hbrBackground = static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
wc.lpszMenuName = L"None"; wc.lpszMenuName = L"None";
wc.lpszClassName = ApplicationName.c_str(); wc.lpszClassName = ApplicationName.c_str();
if (!RegisterClassExW(&wc)) return FALSE; if (!RegisterClassExW(&wc)) return FALSE;
if (!SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) Logger.print(L"SetProcessDpiAwarenessContext failed. LastError:", GetLastError()); if (!SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) Logger.print(L"SetProcessDpiAwarenessContext failed. LastError:", GetLastError());
MainInstance = hInstance; MainInstance = hInstance;
MainWindowHandle = CreateWindowExW(0, wc.lpszClassName, wc.lpszClassName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr); MainWindowHandle = CreateWindowExW(0, wc.lpszClassName, wc.lpszClassName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);
SetWindowLongW(MainWindowHandle, GWL_STYLE, WS_VISIBLE | WS_MAXIMIZEBOX); SetWindowLongW(MainWindowHandle, GWL_STYLE, WS_VISIBLE | WS_MAXIMIZEBOX | WS_MAXIMIZE);
MARGINS margins{ constexpr MARGINS margins{
.cxLeftWidth = 0, .cxLeftWidth = 0,
.cxRightWidth = 0, .cxRightWidth = 0,
.cyTopHeight = 0, .cyTopHeight = 0,
.cyBottomHeight = 0 .cyBottomHeight = 0
}; };
// margins = { -1 };
RemoveDefaultCaption(MainWindowHandle, &margins); RemoveDefaultCaption(MainWindowHandle, &margins);
// DWM_BLURBEHIND blur{ int a = -40;
// .dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION | DWM_BB_TRANSITIONONMAXIMIZED, game.tasks.pushNewed(new Task([&a](Task& self) {
// .fEnable = TRUE, if (a) {
// .hRgnBlur = CreateRectRgn(0, 0, 400, 400), ++a;
// .fTransitionOnMaximized = FALSE SetLayeredWindowAttributes(MainWindowHandle, 0xffffff, static_cast<BYTE>(0xff * (40 + a) / 40), LWA_COLORKEY | LWA_ALPHA);
// }; } else {
// DwmEnableBlurBehindWindow(MainWindowHandle, &blur); SetLayeredWindowAttributes(MainWindowHandle, 0xffffff, 0xff, LWA_COLORKEY | LWA_ALPHA);
// DeleteObject(blur.hRgnBlur); self.schedulePop(true);
SetWindowLongW(MainWindowHandle, GWL_EXSTYLE, GetWindowLongW(MainWindowHaTndle, GWL_EXSTYLE) | WS_EX_LAYERED); SetWindowLongW(MainWindowHandle, GWL_EXSTYLE, GetWindowLongW(MainWindowHandle, GWL_EXSTYLE) & ~WS_EX_LAYERED);
}
return 0;
}));
SetWindowLongW(MainWindowHandle, GWL_EXSTYLE, GetWindowLongW(MainWindowHandle, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(MainWindowHandle, 0xffffff, 0xe0, LWA_COLORKEY | LWA_ALPHA); SetLayeredWindowAttributes(MainWindowHandle, 0xffffff, 0xe0, LWA_COLORKEY | LWA_ALPHA);
ShowWindow(MainWindowHandle, nCmdShow); ShowWindow(MainWindowHandle, SW_SHOWMAXIMIZED);
SetConsoleOutputCP(65001);
const HHOOK hook = SetWindowsHookW(WH_GETMESSAGE, HookProc);
const HACCEL hAccelTable = LoadAcceleratorsW(hInstance, MAKEINTRESOURCE(109));
if (!hook) MainLogFile << L"SetWindowsHookW failed. LastError: " << GetLastError() << std::endl;
test();
{ {
interactManager.initialize(); interactManager.initialize();
}
SetConsoleOutputCP(65001);
HHOOK hook = SetWindowsHookW(WH_GETMESSAGE, HookProc);
test();
HACCEL hAccelTable = LoadAcceleratorsW(hInstance, MAKEINTRESOURCE(109));
MSG msg = { nullptr };
GameThread = Thread(gameThread); GameThread = Thread(gameThread);
RenderThread = Thread(renderThread); RenderThread = Thread(renderThread);
}
MSG msg = { nullptr };
while (GetMessageW(&msg, nullptr, 0, 0)) { while (GetMessageW(&msg, nullptr, 0, 0)) {
if (!TranslateAcceleratorW(msg.hwnd, hAccelTable, &msg)) { if (!TranslateAcceleratorW(msg.hwnd, hAccelTable, &msg)) {
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessageW(&msg); DispatchMessageW(&msg);
} }
} }
{
isRunning = false; isRunning = false;
if (GameThread.joinable()) GameThread.join(); if (GameThread.joinable()) GameThread.join();
if (RenderThread.joinable()) RenderThread.join(); if (RenderThread.joinable()) RenderThread.join();
}
DestroyAcceleratorTable(hAccelTable); DestroyAcceleratorTable(hAccelTable);
UnhookWindowsHookEx(hook); UnhookWindowsHookEx(hook);
_wsystem(L"pause");
for (const auto& [addr, info] : memoryManager.allocated) { Logger.print(L"using", addr, info.size, L"B", info.msg); } for (const auto& [addr, info] : memoryManager.allocated) { Logger.print(L"using", addr, info.size, L"B", info.msg); }
MainLogFile << L"-------- Program End --------" << std::endl; MainLogFile << L"-------- Program End --------" << std::endl;
for (const auto& [addr, info] : memoryManager.allocated) { MainLogFile << L" using " << addr << L" " << info.size << L"B " << info.msg << std::endl; } for (const auto& [addr, info] : memoryManager.allocated) { MainLogFile << L" using " << addr << L" " << info.size << L"B " << info.msg << std::endl; }
_wsystem(L"pause"); _wsystem(L"pause");
_wsystem(L"pause");
return static_cast<int>(msg.wParam); return static_cast<int>(msg.wParam);
} }
@@ -318,9 +324,10 @@ struct Release {
Release() = default; Release() = default;
~Release() { ~Release() {
delete &gc;
MainLogFile << L"--------- Last Check ---------" << std::endl; MainLogFile << L"--------- Last Check ---------" << std::endl;
for (const auto& [addr, info] : memoryManager.allocated) { MainLogFile << L" using " << addr << L" " << info.size << L"B " << info.msg << std::endl; } for (const auto& [addr, info] : memoryManager.allocated) { MainLogFile << L" using " << addr << L" " << info.size << L"B " << info.msg << std::endl; }
MainLogFile.close(); MainLogFile.close();
delete &MainLogFile; delete &MainLogFile;
} }
} x; } NEVER_REFERENCED_release;
+15 -6
View File
@@ -1,8 +1,11 @@
// //
// Created by EmsiaetKadosh on 25-3-4. // Created by EmsiaetKadosh on 25-3-4.
// //
#pragma once #pragma once
#include "gc.h"
template <typename T, typename L = void> template <typename T, typename L = void>
class AnywhereEditable; class AnywhereEditable;
template <typename T, typename L = void> template <typename T, typename L = void>
@@ -11,6 +14,7 @@ template <typename T, typename L = void>
class AnywhereIterator; class AnywhereIterator;
class AnywhereIteratorEnd; class AnywhereIteratorEnd;
/** /**
* 此处无法进行代码编译层面的直接约束 * 此处无法进行代码编译层面的直接约束
* @tparam T 满足T extends AnywhereEditable<T, L> * @tparam T 满足T extends AnywhereEditable<T, L>
@@ -33,9 +37,8 @@ private:
public: public:
byte reserved[7]{}; // reserved[0]: Task::schedulePop byte reserved[7]{}; // reserved[0]: Task::schedulePop
public:
AnywhereEditable() = default; AnywhereEditable() = default;
AnywhereEditable(const AnywhereEditable& other) {} AnywhereEditable(const AnywhereEditable&) {}
AnywhereEditable(AnywhereEditable&& other) noexcept : prev(other->prev), next(other->next), list(other->list) { AnywhereEditable(AnywhereEditable&& other) noexcept : prev(other->prev), next(other->next), list(other->list) {
other->prev = nullptr; other->prev = nullptr;
@@ -65,7 +68,7 @@ class AnywhereIterator {
AnywhereEditable<T, L>* current; AnywhereEditable<T, L>* current;
public: public:
explicit AnywhereIterator(AnywhereEditable<T, L>* current) : current(current) {} AnywhereIterator(AnywhereEditable<T, L>* current) : current(current) {}
AnywhereIterator(const AnywhereIterator& other) = default; AnywhereIterator(const AnywhereIterator& other) = default;
T& operator*() noexcept(false) { T& operator*() noexcept(false) {
@@ -116,7 +119,7 @@ public:
class AnywhereIteratorEnd { class AnywhereIteratorEnd {
public: public:
AnywhereIteratorEnd() {} AnywhereIteratorEnd() = default;
AnywhereIteratorEnd(const AnywhereIteratorEnd& other) = delete; AnywhereIteratorEnd(const AnywhereIteratorEnd& other) = delete;
AnywhereIteratorEnd(AnywhereIteratorEnd&& other) = delete; AnywhereIteratorEnd(AnywhereIteratorEnd&& other) = delete;
@@ -160,7 +163,13 @@ template <typename T, typename L>
int AnywhereEditable<T, L>::pushThis(AnywhereEditableList<T, L>& list) noexcept { return list.pushThis(static_cast<T*>(this)); } int AnywhereEditable<T, L>::pushThis(AnywhereEditableList<T, L>& list) noexcept { return list.pushThis(static_cast<T*>(this)); }
template <typename T, typename L> template <typename T, typename L>
int AnywhereEditable<T, L>::pop() noexcept { return list->pop(static_cast<T*>(this)); } int AnywhereEditable<T, L>::pop() noexcept {
if (!list) {
Logger.error(L"AnywhereEditable::pop() : list is null");
Failed();
}
return list->pop(static_cast<T*>(this));
}
template <typename T, typename L> template <typename T, typename L>
bool AnywhereIterator<T, L>::operator!=(const AnywhereIteratorEnd& other) const noexcept { return other != *this; } bool AnywhereIterator<T, L>::operator!=(const AnywhereIteratorEnd& other) const noexcept { return other != *this; }
@@ -205,6 +214,6 @@ int AnywhereEditableList<T, L>::pop(T* value) noexcept {
value->list = nullptr; value->list = nullptr;
value->next->prev = value->prev; value->next->prev = value->prev;
value->prev->next = value->next; value->prev->next = value->next;
if (value->managedByList) delete deallocating(value); if (value->managedByList) gc.submit(value);
Success(); Success();
} }
+9
View File
@@ -0,0 +1,9 @@
//
// Created by EmsiaetKadosh on 25-3-13.
//
#pragma once
#pragma warning(disable: 4554)
#pragma warning(default: 4555)
#pragma warning(disable: 5030)
+24 -10
View File
@@ -8,28 +8,42 @@
class StartWindow final : public Window { class StartWindow final : public Window {
TranslatableText title = TranslatableText(L"hbp.title"); TranslatableText title = TranslatableText(L"hbp.title");
StartWindow() { StartWindow() {
Button* start = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.1, 0.4, 0.08, Location::CENTER, LiteralText(L"\\#ff44ee66Exit")))).ptr()); Button* start = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.1, 0.4, 0.08, Location::CENTER, LiteralText(L"\\f\4\\#ff44ee66Exit")))).ptr());
start->onTick = [start, this](int) { if (start->containsMouse()) game.getFloatWindow().push(L"\\#ff44ee66退出游戏"_renderable); }; start->onTick = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(L"\\#ff44ee66退出游戏"_renderable); };
start->mouseUp = [](int) { start->mouseClick = [](Widget&, MouseButtonCode) {
game.setWindow(&ConfirmWindow::of(LiteralText(L"是否\\#ff44ee66退出游戏\\r"))->requireCancel().requireConfirm([](Button& confirm) { game.setWindow(&ConfirmWindow::of(LiteralText(L"是否\\#ff44ee66退出游戏\\r"))->requireCancel().requireConfirm([](Button& confirm) {
confirm.mouseUp = [](int) { DestroyWindow(MainWindowHandle); }; confirm.mouseClick = [](Widget&, MouseButtonCode) { DestroyWindow(MainWindowHandle); };
confirm.onTick = [&confirm](int) { confirm.onTick = [](Widget& self, MouseButtonCode) {
if (confirm.containsMouse()) { if (self.containsMouse()) {
game.getFloatWindow().push(L"\\#ff44ee66确定退出游戏"_renderable); game.getFloatWindow().push(L"\\#ff44ee66确定退出游戏"_renderable);
confirm.backgroundColor.hover = confirm.animation.adaptsColor(0x99008800, 0x9900ff00); self.backgroundColor.hover = static_cast<Button&>(self).animation.adaptsColor(0x99008800, 0x9900ff00);
}
};
}));
};
Button* optn = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.2, 0.4, 0.08, Location::CENTER, LiteralText(L"\\f\4\\#ff4488eeOptions")))).ptr());
optn->onTick = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(L"\\#ff4488ee设置"_renderable); };
Button* exit = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.3, 0.4, 0.08, Location::CENTER, LiteralText(L"\\f\4\\#ffee0000Start")))).ptr());
exit->onTick = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(L"\\#ffee0000开始游戏"_renderable); };
exit->mouseClick = [](Widget&, MouseButtonCode) {
game.setWindow(&ConfirmWindow::of(LiteralText(L"是否\\#ffee0000退出游戏\\r"))->requireCancel().requireConfirm([](Button& confirm) {
confirm.mouseClick = [](Widget&, MouseButtonCode) { DestroyWindow(MainWindowHandle); };
confirm.onTick = [](Widget& self, MouseButtonCode) {
if (self.containsMouse()) {
game.getFloatWindow().push(L"\\#ff44ee66确定退出游戏"_renderable);
self.backgroundColor.hover = static_cast<Button&>(self).animation.adaptsColor(0x99008800, 0x9900ff00);
} }
}; };
})); }));
}; };
Button* test = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.2, 0.4, 0.08, Location::CENTER, LiteralText(L"\\#ff4488eeOptions")))).ptr());
Button* exit = dynamic_cast<Button*>(widgets.emplace_back(std::move(Button(0, 0.3, 0.4, 0.08, Location::CENTER, LiteralText(L"\\#ffee0000Start")))).ptr());
exit->onTick = [exit](int) { if (exit->containsMouse()) game.getFloatWindow().push(L"\\#ffee0000开始游戏"_renderable); };
} }
public: public:
static StartWindow* create() noexcept { return allocatedFor(new StartWindow()); } static StartWindow* create() noexcept { return allocatedFor(new StartWindow()); }
void onClose() override { pop(); } void onClose() override { pop(); }
void render() const noexcept override { void render() const noexcept override {
fontManager.getDefault().drawCenter(title.getRenderableString(), 0, 0, renderer.getWidth(), renderer.getHeight()); fontManager.getDefault().drawCenter(title.getRenderableString(), 0, 0, renderer.getWidth(), renderer.getHeight());
Window::render(); Window::render();