格式整理
This commit is contained in:
+65
@@ -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
@@ -30,7 +30,7 @@ private:
|
||||
bool doReverse = true;
|
||||
|
||||
public:
|
||||
Animation() noexcept {}
|
||||
Animation() noexcept = default;
|
||||
|
||||
Animation& allowPositiveSuper(const bool val = true) noexcept {
|
||||
positiveSuperAllowed = val;
|
||||
@@ -42,12 +42,12 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
Animation& depends(Depend depend) noexcept {
|
||||
Animation& depends(const Depend depend) noexcept {
|
||||
this->depend = depend;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Animation& features(Style style) noexcept {
|
||||
Animation& features(const Style style) noexcept {
|
||||
this->style = style;
|
||||
return *this;
|
||||
}
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
Animation& setDuration(const unsigned int val) noexcept {
|
||||
Animation& setDuration(const int val) noexcept {
|
||||
if (duration == 0) duration = 1;
|
||||
duration = val;
|
||||
return *this;
|
||||
@@ -70,11 +70,11 @@ public:
|
||||
|
||||
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 >= 1.0) return 1.0;
|
||||
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 {
|
||||
|
||||
@@ -57,18 +57,18 @@ static constexpr wchar Table16[17] = L"0123456789ABCDEF";
|
||||
String ret;
|
||||
if (fills >= 8 || value < static_cast<unsigned int>(1) << fills * 4) {
|
||||
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];
|
||||
value >>= 4;
|
||||
}
|
||||
} else {
|
||||
unsigned int i = 0;
|
||||
while (i < 8) {
|
||||
if ((value >> i) & 0xf) break;
|
||||
if (value >> i & 0xf) break;
|
||||
++i;
|
||||
}
|
||||
while (i < 8) {
|
||||
ret.push_back(Table16[(value >> i) & 0xf]);
|
||||
ret.push_back(Table16[value >> i & 0xf]);
|
||||
++i;
|
||||
}
|
||||
if (ret.empty()) ret = L"0";
|
||||
@@ -86,18 +86,18 @@ static constexpr wchar Table16[17] = L"0123456789ABCDEF";
|
||||
String ret;
|
||||
if (fills >= 16 || value < static_cast<QWORD>(1) << fills * 4) {
|
||||
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];
|
||||
value >>= 4;
|
||||
}
|
||||
} else {
|
||||
QWORD i = 0;
|
||||
while (i < 16) {
|
||||
if ((value >> i) & 0xf) break;
|
||||
if (value >> i & 0xf) break;
|
||||
++i;
|
||||
}
|
||||
while (i < 16) {
|
||||
ret.push_back(Table16[(value >> i) & 0xf]);
|
||||
ret.push_back(Table16[value >> i & 0xf]);
|
||||
++i;
|
||||
}
|
||||
if (ret.empty()) ret = L"0";
|
||||
|
||||
@@ -4,17 +4,88 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
class File {
|
||||
public:
|
||||
std::wfstream file;
|
||||
explicit File(const std::wstring& path) : file(path, std::ios::in | std::ios::out | std::ios::binary) {}
|
||||
String path{};
|
||||
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& 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 {
|
||||
public:
|
||||
enum class DataType : int {
|
||||
enum class DataType : unsigned char {
|
||||
Integer, Double, String, Boolean, Null, List, Object
|
||||
};
|
||||
|
||||
@@ -34,9 +105,7 @@ class DataLoader {
|
||||
while (!file.file.eof()) {
|
||||
wchar c = file.file.get();
|
||||
if (c == L'\"') Success();
|
||||
if (c == L'\\') {
|
||||
c = file.file.get();
|
||||
}
|
||||
if (c == L'\\') { c = file.file.get(); }
|
||||
}
|
||||
errorInfo = L"Error: String never ends. EOF comes before a '\"'";
|
||||
Failed();
|
||||
@@ -45,7 +114,7 @@ class DataLoader {
|
||||
int loadUntil(int& line, wchar at = 0) {
|
||||
String name = {};
|
||||
String val = {};
|
||||
enum { identifier, eq, value, end } status = identifier;
|
||||
enum : unsigned char { identifier, eq, value, end } status = identifier;
|
||||
while (!file.file.eof()) {
|
||||
const wchar c = file.file.get();
|
||||
if (c == L'\n') ++line;
|
||||
@@ -72,12 +141,17 @@ class DataLoader {
|
||||
|
||||
public:
|
||||
String errorInfo = {};
|
||||
explicit DataLoader(const String& path) : file(path) {}
|
||||
DataLoader(const String& path) : file(path) {}
|
||||
DataLoader(const DataLoader&) = delete;
|
||||
DataLoader(DataLoader&&) = delete;
|
||||
DataLoader& operator=(const DataLoader&) = delete;
|
||||
DataLoader& operator=(DataLoader&&) = delete;
|
||||
~DataLoader() = default;
|
||||
|
||||
int load() {
|
||||
int line = 1;
|
||||
return loadUntil(line);
|
||||
}
|
||||
};
|
||||
|
||||
inline File& [[carlbeks::releasedat]] MainLogFile = (new File(L"log.txt"))->binary().inputs().outputs().truncate().open().operator<<(L"initialize MainLogFile\n");
|
||||
|
||||
@@ -9,10 +9,9 @@
|
||||
#include "gc.h"
|
||||
#include "Hud.h"
|
||||
#include "Task.h"
|
||||
#include "utils.h"
|
||||
#include "Window.h"
|
||||
|
||||
class Game final : public IRenderable {
|
||||
class Game final /* : public IRenderable, public ITickable */ {
|
||||
friend void gameThread();
|
||||
WindowManager windows;
|
||||
Hud hud = Hud(); // 8
|
||||
@@ -21,14 +20,16 @@ class Game final : public IRenderable {
|
||||
QWORD currentTick = 0; // 8
|
||||
|
||||
public:
|
||||
mutable GarbageCollector gc;
|
||||
TaskScheduler tasks; // 8
|
||||
std::minstd_rand random;
|
||||
|
||||
explicit Game();
|
||||
~Game() override;
|
||||
Game();
|
||||
~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;
|
||||
renderer.gameStartRender();
|
||||
caption->render();
|
||||
@@ -46,7 +47,7 @@ public:
|
||||
int setWindow(Window* window) noexcept {
|
||||
if (window) {
|
||||
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);
|
||||
Success();
|
||||
}
|
||||
@@ -59,15 +60,11 @@ public:
|
||||
[[nodiscard]] FloatWindow& getFloatWindow() const noexcept { return *floatWindow; }
|
||||
|
||||
[[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");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] QWORD getTick() const noexcept { return currentTick; }
|
||||
|
||||
int closeWindow(Window* const window) noexcept { return windows.pop(window); }
|
||||
|
||||
void tick() noexcept {
|
||||
++currentTick;
|
||||
floatWindow->clear();
|
||||
@@ -89,7 +86,7 @@ public:
|
||||
|
||||
void passEvent(const MouseActionCode action, const MouseButtonCode value, const int x, const int y) const noexcept {
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "Chars.h"
|
||||
#include "def.h"
|
||||
#include "Chars.h"
|
||||
#include "InteractManager.h"
|
||||
|
||||
class LiteralText;
|
||||
@@ -37,7 +38,7 @@ class RenderableString {
|
||||
FontStyle style = 0;
|
||||
FontID idFont = 0;
|
||||
|
||||
explicit StringConfig() = default;
|
||||
StringConfig() = default;
|
||||
|
||||
void reset() noexcept {
|
||||
idFont = 0;
|
||||
@@ -109,10 +110,10 @@ class RenderableString {
|
||||
using ConstIterator = List<StringConfig>::const_iterator;
|
||||
|
||||
public:
|
||||
explicit RenderableString(const String& string): RenderableString(string.c_str(), string.length()) {}
|
||||
explicit RenderableString(String&& string) : RenderableString(string.c_str(), string.length()) {}
|
||||
RenderableString(const 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);
|
||||
else parseAppend(string, length);
|
||||
}
|
||||
@@ -171,8 +172,8 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
int getHeight() const noexcept;
|
||||
int getWidth(FontID defaultID = 1) const noexcept;
|
||||
[[nodiscard]] int getHeight() const noexcept;
|
||||
[[nodiscard]] int getWidth(FontID defaultID = 0) const noexcept;
|
||||
int getWidth(RenderConfig* renderConfigs, FontID defaultID) const noexcept;
|
||||
|
||||
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 {
|
||||
public:
|
||||
Function<void(int width, int height)> resize;
|
||||
|
||||
private:
|
||||
friend class ObjectHolder<Font>;
|
||||
friend class FontManager;
|
||||
friend class RenderableString;
|
||||
const String name;
|
||||
@@ -374,9 +374,9 @@ private:
|
||||
const FontID id;
|
||||
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:
|
||||
Font(const Font&) = default;
|
||||
@@ -427,11 +427,11 @@ public:
|
||||
class FontManager {
|
||||
Map<FontID, Font> fonts;
|
||||
Font *defaultFont, *captionFont;
|
||||
FontID assigned = 1;
|
||||
FontID assigned = 0;
|
||||
using IterFonts = Map<FontID, Font>::const_iterator;
|
||||
|
||||
public:
|
||||
explicit FontManager() {
|
||||
FontManager() {
|
||||
captionFont = &newFont(L"Microsoft YaHei UI Light");
|
||||
defaultFont = &newFont(L"Microsoft YaHei UI Light");
|
||||
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;
|
||||
}
|
||||
|
||||
Font& getDefault() const noexcept { return *defaultFont; }
|
||||
[[nodiscard]] Font& getDefault() const noexcept { return *defaultFont; }
|
||||
|
||||
void resize(const int width, const int height) {
|
||||
for (auto& font : fonts | std::views::values)
|
||||
if (font.resize) font.resize(width, height);
|
||||
else {
|
||||
font.height = interactSettings.actual.fontHeight * font.heightModifier;
|
||||
font.yOffsetPx = font.height * font.yOffset;
|
||||
font.height = static_cast<long>(interactSettings.actual.fontHeight * font.heightModifier);
|
||||
font.yOffsetPx = static_cast<long>(font.height * font.yOffset);
|
||||
font.clear();
|
||||
}
|
||||
}
|
||||
@@ -487,8 +487,8 @@ typedef class LiteralText final : public IText {
|
||||
mutable RenderableString renderableString;
|
||||
|
||||
public:
|
||||
explicit LiteralText(const String& string): string(string), renderableString(string) {}
|
||||
explicit LiteralText(String&& string): string(std::move(string)), renderableString(this->string) {}
|
||||
LiteralText(const String& string): string(string), renderableString(string) {}
|
||||
LiteralText(String&& string): string(std::move(string)), renderableString(this->string) {}
|
||||
|
||||
const String& getText() const noexcept override { return string; }
|
||||
|
||||
@@ -501,8 +501,8 @@ class TranslatableText final : public IText {
|
||||
mutable QWORD langConfig = 0;
|
||||
|
||||
public:
|
||||
explicit TranslatableText(const String& id) : idSrc(id) {}
|
||||
explicit TranslatableText(String&& id) : idSrc(std::move(id)) {}
|
||||
TranslatableText(const String& id) : idSrc(id) {}
|
||||
TranslatableText(String&& id) : idSrc(std::move(id)) {}
|
||||
const String& getText() const noexcept override;
|
||||
const RenderableString& getRenderableString() const noexcept override;
|
||||
void refreshText() const noexcept;
|
||||
@@ -524,7 +524,7 @@ class Translator {
|
||||
using IterLang = List<Language>::const_iterator;
|
||||
|
||||
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(String&& lang) noexcept { langMap.insert(std::make_pair(lang, ++idLangMax)); }
|
||||
void loadLang();
|
||||
|
||||
+1
-1
@@ -280,4 +280,4 @@ bool InteractManager::isInClientCaption() const noexcept { return mouseX > inter
|
||||
|
||||
|
||||
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
@@ -62,7 +62,7 @@ class InteractManager {
|
||||
|
||||
public:
|
||||
void initialize() noexcept { trackMouseEvent.hwndTrack = MainWindowHandle; }
|
||||
explicit InteractManager();
|
||||
InteractManager();
|
||||
|
||||
void update(const int keyCode, const bool isPressed) noexcept {
|
||||
if (keyCode >= 256) return;
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
[[nodiscard]] bool isInClientCaption() const noexcept;
|
||||
[[nodiscard]] KeyStatus& getKey(const int keyCode) noexcept { return keyStatus[keyCode]; }
|
||||
[[nodiscard]] KeyStatus& getKey(const KeyBinding& binding) noexcept;
|
||||
[[nodiscard]] int getMouseButtonCode() const noexcept;
|
||||
[[nodiscard]] unsigned int /*MouseButtonCode*/ getMouseButtonCode() const noexcept;
|
||||
|
||||
int dealMouseWheel() noexcept {
|
||||
const int ret = mouseWheel;
|
||||
|
||||
+9
-11
@@ -73,8 +73,8 @@ class Renderer final : public ITickable {
|
||||
|
||||
public:
|
||||
byte windowSize = 0; // 1, Windows: SIZE_***
|
||||
byte reserved[5] {};
|
||||
Task resizeReloadBitmap { [this](Task& task) {
|
||||
byte reserved[5]{};
|
||||
Task resizeReloadBitmap{ [this](Task& task) {
|
||||
Logger.info(L"Scheduled task: resize reload bitmap " + std::to_wstring(windowWidth) + L" * " + std::to_wstring(windowHeight));
|
||||
if (!canvasBitmap) {
|
||||
canvasBitmap = CreateCompatibleBitmap(MainDC, windowWidth, windowHeight);
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
}
|
||||
if (canvasBitmap && assistBitmap) {
|
||||
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();
|
||||
}
|
||||
Logger.print(task.reserved[0]);
|
||||
@@ -94,11 +94,10 @@ public:
|
||||
|
||||
private:
|
||||
void gameStartRender() noexcept;
|
||||
|
||||
void gameEndRender() noexcept;
|
||||
|
||||
public:
|
||||
explicit Renderer() { Logger.put(L"Renderer created"); }
|
||||
Renderer() { Logger.put(L"Renderer created"); }
|
||||
|
||||
~Renderer() override {
|
||||
Logger.put(L"Renderer destroyed");
|
||||
@@ -128,7 +127,7 @@ public:
|
||||
* @param argb ARGB式颜色
|
||||
* @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"); }
|
||||
|
||||
@@ -167,7 +166,7 @@ public:
|
||||
.right = x + w,
|
||||
.bottom = y + h
|
||||
};
|
||||
HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
|
||||
const HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
|
||||
FillRect(canvasDC, &rect, clr);
|
||||
deleteObject(clr);
|
||||
} else {
|
||||
@@ -178,7 +177,7 @@ public:
|
||||
.bottom = y + h > windowHeight ? windowHeight - y : h
|
||||
};
|
||||
blendFunction.SourceConstantAlpha = color >> 24;
|
||||
HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
|
||||
const HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
|
||||
FillRect(assistDC, &rect, 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");
|
||||
@@ -189,8 +188,7 @@ public:
|
||||
assertRendering();
|
||||
//assertRenderThread();
|
||||
if ((color & 0xff000000) == 0) return;
|
||||
if ((color & 0xff000000) == 0xff000000) {
|
||||
HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
|
||||
if ((color & 0xff000000) == 0xff000000) { const HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
|
||||
FillRect(canvasDC, rect, clr);
|
||||
deleteObject(clr);
|
||||
} else {
|
||||
@@ -201,7 +199,7 @@ public:
|
||||
.bottom = rect->bottom > windowHeight ? windowHeight : rect->bottom - rect->top
|
||||
};
|
||||
blendFunction.SourceConstantAlpha = color >> 24;
|
||||
HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
|
||||
const HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
|
||||
FillRect(assistDC, &r, 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");
|
||||
|
||||
@@ -10,12 +10,15 @@ class TaskScheduler;
|
||||
|
||||
class Task final : public AnywhereEditable<Task> {
|
||||
friend class TaskScheduler;
|
||||
#ifndef __CARLBEKS_DEBUG__
|
||||
QWORD triggerInterval = 0, nextExecuteTime = 0, lastExecuteTime = 0;
|
||||
#endif
|
||||
|
||||
public:
|
||||
Function<void(Task& self)> func;
|
||||
|
||||
explicit Task(const Function<void(Task& self)>& func) : func(func) {}
|
||||
explicit Task(Function<void(Task& self)>&& func) : func(std::move(func)) {}
|
||||
Task(const Function<void(Task& self)>& func) : func(func) {}
|
||||
Task(Function<void(Task& self)>&& func) : func(std::move(func)) {}
|
||||
void schedulePop(const bool pop) noexcept { reserved[0] = pop; }
|
||||
[[nodiscard]] bool scheduledPop() const noexcept { return reserved[0]; }
|
||||
|
||||
@@ -23,6 +26,12 @@ public:
|
||||
schedulePop(true);
|
||||
Success();
|
||||
}
|
||||
#ifndef __CARLBEKS_DEBUG__
|
||||
Task& every(QWORD tick);
|
||||
Task& after(QWORD tick);
|
||||
Task& until(QWORD tick);
|
||||
Task& forever();
|
||||
#endif
|
||||
};
|
||||
|
||||
class TaskScheduler {
|
||||
@@ -34,7 +43,7 @@ public:
|
||||
task.func(task);
|
||||
if (task.scheduledPop()) {
|
||||
task.schedulePop(false);
|
||||
tasks.pop(&task);
|
||||
tasks.pop(&task); // pop后删除了内存,迭代器的current失效
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-15
@@ -5,18 +5,3 @@
|
||||
#pragma once
|
||||
|
||||
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
@@ -9,14 +9,14 @@
|
||||
#include "InteractManager.h"
|
||||
|
||||
int Window::pop() noexcept {
|
||||
game.gc.submit(this);
|
||||
gc.submit(this);
|
||||
Success();
|
||||
}
|
||||
|
||||
void Window::render() const noexcept { for (const ObjectHolder<Widget>& widget : widgets) widget->render(); }
|
||||
void Window::tick() noexcept { for (ObjectHolder<Widget>& widget : widgets) widget->tick(); }
|
||||
void Window::onResize() { for (ObjectHolder<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::render() const noexcept { for (const Widget* widget : widgets) widget->render(); }
|
||||
void Window::tick() noexcept { for (Widget* widget : widgets) widget->tick(); }
|
||||
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 (Widget* widget : widgets) widget->passEvent(action, value, x, y); }
|
||||
|
||||
int WindowManager::pop(Window* value) noexcept {
|
||||
if (value->list != static_cast<AnywhereEditableList*>(this)) {
|
||||
@@ -40,19 +40,20 @@ void WindowManager::clear() noexcept {
|
||||
}
|
||||
|
||||
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->backgroundColor.hover = 0xffee0000;
|
||||
close->backgroundColor.active = 0;
|
||||
close->backgroundColor.inactive = 0xffaaaaaa;
|
||||
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.active = 0xff000000;
|
||||
close->foregroundColor.inactive = 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->backgroundColor.hover = 0xffcccccc;
|
||||
minmax->backgroundColor.active = 0;
|
||||
@@ -62,7 +63,9 @@ CaptionWindow::CaptionWindow() {
|
||||
minmax->foregroundColor.active = 0xff000000;
|
||||
minmax->foregroundColor.inactive = 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->backgroundColor.hover = 0xffcccccc;
|
||||
hide->backgroundColor.active = 0;
|
||||
@@ -72,7 +75,15 @@ CaptionWindow::CaptionWindow() {
|
||||
hide->foregroundColor.active = 0xff000000;
|
||||
hide->foregroundColor.inactive = 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->backgroundColor.hover = 0xffcccccc;
|
||||
options->backgroundColor.active = 0;
|
||||
@@ -82,13 +93,6 @@ CaptionWindow::CaptionWindow() {
|
||||
options->foregroundColor.active = 0xff000000;
|
||||
options->foregroundColor.inactive = 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"); }
|
||||
@@ -96,12 +100,12 @@ void CaptionWindow::onClose() { throw InvalidOperationException(L"Should not clo
|
||||
|
||||
void CaptionWindow::render() const noexcept {
|
||||
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() {
|
||||
int left = 0, right = 0;
|
||||
for (ObjectHolder<Widget>& widget : widgets) {
|
||||
for (Widget* widget : widgets) {
|
||||
widget->w = interactSettings.actual.captionHeight;
|
||||
widget->h = interactSettings.actual.captionHeight;
|
||||
switch (widget->location) {
|
||||
@@ -132,7 +136,7 @@ void FloatWindow::render() const noexcept {
|
||||
x = interactManager.getMouseX();
|
||||
y = interactManager.getMouseY();
|
||||
int height = 0, width = 0;
|
||||
for (const ObjectHolder<RenderableString>& str : strings.get()) {
|
||||
for (const RenderableString* str : strings.get()) {
|
||||
height += str->getHeight();
|
||||
if (str->getWidth() > width) width = str->getWidth();
|
||||
}
|
||||
@@ -147,8 +151,8 @@ void FloatWindow::render() const noexcept {
|
||||
const int xf = x + interactSettings.actual.floatWindowMargin;
|
||||
int yf = y + interactSettings.actual.floatWindowMargin;
|
||||
|
||||
for (const ObjectHolder<RenderableString>& str : strings.get()) {
|
||||
fontManager.get(1).draw(*str, xf, yf);
|
||||
for (const RenderableString* str : strings.get()) {
|
||||
fontManager.getDefault().draw(*str, xf, yf);
|
||||
yf += str->getHeight();
|
||||
}
|
||||
|
||||
@@ -159,7 +163,7 @@ void FloatWindow::render() const noexcept {
|
||||
unsigned int Widget::colorSelector(const Color& clr) const {
|
||||
if (!isActive) return clr.inactive;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -208,24 +212,24 @@ void Widget::onResize() {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
width = renderer.getWidth() * w;
|
||||
height = renderer.getHeight() * h;
|
||||
width = static_cast<int>(renderer.getWidth() * w);
|
||||
height = static_cast<int>(renderer.getHeight() * h);
|
||||
switch (location) {
|
||||
case Location::LEFT_TOP:
|
||||
left = renderer.getWidth() * x;
|
||||
top = renderer.getHeight() * y;
|
||||
left = static_cast<int>(renderer.getWidth() * x);
|
||||
top = static_cast<int>(renderer.getHeight() * y);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
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;
|
||||
break;
|
||||
case Location::TOP:
|
||||
left = static_cast<int>(renderer.getWidth() * x) + (renderer.getWidth() - width >> 1);
|
||||
top = renderer.getHeight() * y;
|
||||
top = static_cast<int>(renderer.getHeight() * y);
|
||||
break;
|
||||
case Location::CENTER:
|
||||
left = static_cast<int>(renderer.getWidth() * x) + (renderer.getWidth() - width >> 1);
|
||||
@@ -237,7 +241,7 @@ void Widget::onResize() {
|
||||
break;
|
||||
case Location::RIGHT_TOP:
|
||||
left = static_cast<int>(renderer.getWidth() * x) + renderer.getWidth() - width;
|
||||
top = renderer.getHeight() * y;
|
||||
top = static_cast<int>(renderer.getHeight() * y);
|
||||
break;
|
||||
case Location::RIGHT:
|
||||
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->x = 0;
|
||||
}
|
||||
confirm->onTick = [this](int) { if (confirm->containsMouse()) confirm->backgroundColor.hover = confirm->animation.adaptsColor(0x99008800, 0x9900ff00); };
|
||||
confirm->mouseLeave = [this](int) { confirm->animation.reset(); };
|
||||
confirm->onTick = [](Widget& confirm, MouseButtonCode) { if (confirm.containsMouse()) confirm.backgroundColor.hover = static_cast<Button&>(confirm).animation.adaptsColor(0x99008800, 0x9900ff00); };
|
||||
confirm->mouseLeave = [](Widget& confirm, MouseButtonCode) { static_cast<Button&>(confirm).animation.reset(); };
|
||||
if (func) func(*confirm);
|
||||
confirm->onResize();
|
||||
return *this;
|
||||
@@ -286,7 +290,7 @@ ConfirmWindow& ConfirmWindow::requireConfirm(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->mouseUp = [this](int) {
|
||||
cancel->mouseClick = [this](Widget&, MouseButtonCode) {
|
||||
game.tasks.pushNewed(allocatedFor(new Task([this](Task& self) {
|
||||
if (game.closeWindow(this)) this->onClose();
|
||||
self.pop();
|
||||
@@ -311,8 +315,8 @@ ConfirmWindow& ConfirmWindow::requireCancel(const Function<void(Button&)>& func)
|
||||
cancel->x = 0.125;
|
||||
cancel->w = 0.5;
|
||||
}
|
||||
cancel->onTick = [this](int) { if (cancel->containsMouse()) cancel->backgroundColor.hover = cancel->animation.adaptsColor(0x99880000, 0x99ff0000); };
|
||||
cancel->mouseLeave = [this](int) { cancel->animation.reset(); };
|
||||
cancel->onTick = [](Widget& cancel, MouseButtonCode) { if (cancel.containsMouse()) cancel.backgroundColor.hover = static_cast<Button&>(cancel).animation.adaptsColor(0x99880000, 0x99ff0000); };
|
||||
cancel->mouseLeave = [](Widget& cancel, int) { static_cast<Button&>(cancel).animation.reset(); };
|
||||
if (func) func(*cancel);
|
||||
cancel->onResize();
|
||||
return *this;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
class WindowManager;
|
||||
|
||||
enum class MouseActionCode : int {
|
||||
enum class MouseActionCode : unsigned int {
|
||||
MAC_MOVE = 0,
|
||||
MAC_HOVER = 1,
|
||||
MAC_DOWN = 2,
|
||||
@@ -21,7 +21,7 @@ enum class MouseActionCode : int {
|
||||
MAC_LEAVE = 5
|
||||
};
|
||||
|
||||
enum class MouseButtonCodeEnum : int {
|
||||
enum class MouseButtonCodeEnum : unsigned int {
|
||||
MBC_L_DOWN = 0x1,
|
||||
MBC_R_DOWN = 0x2,
|
||||
MBC_M_DOWN = 0x4,
|
||||
@@ -33,20 +33,20 @@ enum class MouseButtonCodeEnum : int {
|
||||
/**
|
||||
* @see MouseButtonCodeEnum
|
||||
*/
|
||||
using MouseButtonCode = int;
|
||||
using MouseButtonCode = unsigned int;
|
||||
|
||||
class Widget : public IRenderable, public ITickable {
|
||||
protected:
|
||||
int left = 0, top = 0, width = 0, height = 0;
|
||||
|
||||
public:
|
||||
using Action = Function<void(int)>;
|
||||
using Action = Function<void(Widget&, MouseButtonCode)>;
|
||||
double x, y, w, h;
|
||||
Action mouseHover; // 传入int为:0,鼠标移动;其余,鼠标在其上的长时间悬浮
|
||||
Action mouseDown; // 传入int表示变更按键。0左, 1中, 2右
|
||||
Action mouseUp; // 传入int表示变更按键。0左, 1中, 2右
|
||||
Action mouseLeave; // 传入int忽略
|
||||
Action mouseClick; // 传入int表示变更按键。0x0左, 0x1中, 0x2右;0xf表示是否双击
|
||||
Action mouseClick; // 传入int表示变更按键。0x0左, 0x1中, 0x2右;0x8表示是否双击
|
||||
Action onTick; // 传入int忽略
|
||||
Color backgroundColor;
|
||||
Color foregroundColor{ TextColor };
|
||||
@@ -54,6 +54,7 @@ public:
|
||||
protected:
|
||||
mutable bool hasMouse = false;
|
||||
mutable bool isActive = true;
|
||||
mutable bool hasMouseTrigger = false;
|
||||
bool isAbsoluteLocation = false;
|
||||
|
||||
public:
|
||||
@@ -61,10 +62,10 @@ public:
|
||||
Location textLocation = Location::CENTER; // 多余字节预声明备用
|
||||
|
||||
protected:
|
||||
char unused[3]{};
|
||||
char unused[2]{};
|
||||
|
||||
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;
|
||||
void render() const noexcept override;
|
||||
@@ -95,12 +96,25 @@ public:
|
||||
}
|
||||
|
||||
virtual void onResize();
|
||||
virtual void onHover(const int value) noexcept { if (mouseHover) mouseHover(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 onMouseLeave(const int value) noexcept { if (mouseLeave) mouseLeave(value); }
|
||||
virtual void onMouseClick(const int value) noexcept { if (mouseClick) mouseClick(value); }
|
||||
void tick() noexcept override { if (onTick) onTick(0); }
|
||||
virtual void onHover(const int value) noexcept { if (mouseHover) mouseHover(*this, value); }
|
||||
|
||||
virtual void onMouseDown(const MouseButtonCode code) noexcept {
|
||||
hasMouseTrigger = true;
|
||||
if (mouseDown) mouseDown(*this, code);
|
||||
}
|
||||
|
||||
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 {
|
||||
if (action == MouseActionCode::MAC_LEAVE || !isMouseIn(x, y)) {
|
||||
@@ -123,7 +137,7 @@ public:
|
||||
onMouseUp(value);
|
||||
break;
|
||||
case MouseActionCode::MAC_DOUBLE:
|
||||
onMouseClick(1);
|
||||
onMouseClick(0x80);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -139,7 +153,7 @@ protected:
|
||||
|
||||
Window() = default;
|
||||
|
||||
~Window() override {}
|
||||
~Window() override = default;
|
||||
|
||||
public:
|
||||
int pop() noexcept override;
|
||||
@@ -164,7 +178,7 @@ public:
|
||||
|
||||
class WindowManager final : public AnywhereEditableList<Window, WindowManager>, public IRenderable, public ITickable {
|
||||
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(); }
|
||||
int pop(Window* value) noexcept override;
|
||||
void clear() noexcept;
|
||||
@@ -173,7 +187,7 @@ public:
|
||||
|
||||
class CaptionWindow final : public Window {
|
||||
public:
|
||||
explicit CaptionWindow();
|
||||
CaptionWindow();
|
||||
bool onOpen() override;
|
||||
void onClose() override;
|
||||
void render() const noexcept override;
|
||||
@@ -184,10 +198,10 @@ class FloatWindow final : public Window {
|
||||
mutable int x = 0; // 标记渲染起始点
|
||||
mutable int y = 0; // 标记渲染起始点
|
||||
typedef List<ObjectHolder<RenderableString>> lt;
|
||||
SynchronizedHolder<lt> strings{};
|
||||
SynchronizedHolder<lt> strings;
|
||||
|
||||
public:
|
||||
explicit FloatWindow() : Window() {
|
||||
FloatWindow() : Window() {
|
||||
strings.setNew<lt>(std::move(lt()));
|
||||
strings.ok();
|
||||
strings.async();
|
||||
@@ -208,8 +222,8 @@ class Button : public Widget {
|
||||
public:
|
||||
ObjectHolder<IText> name;
|
||||
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) {}
|
||||
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, 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, ObjectHolder<IText>&& text) : Widget(x, y, w, h, location), name(std::move(text)) {}
|
||||
void render() const noexcept override;
|
||||
};
|
||||
|
||||
@@ -222,12 +236,11 @@ public:
|
||||
*cancel = nullptr;
|
||||
|
||||
private:
|
||||
explicit ConfirmWindow(const ObjectHolder<IText>& text) : Window(), text(text) {}
|
||||
explicit ConfirmWindow(ObjectHolder<IText>&& text) : Window(), text(std::move(text)) {}
|
||||
ConfirmWindow(const ObjectHolder<IText>& text) : Window(), text(text) {}
|
||||
ConfirmWindow(ObjectHolder<IText>&& text) : Window(), text(std::move(text)) {}
|
||||
|
||||
public:
|
||||
~ConfirmWindow() override { /* 不需要delete,析构时Window会自动delete */
|
||||
}
|
||||
~ConfirmWindow() override = default; // 不需要delete,析构时Window会自动delete
|
||||
|
||||
void render() const noexcept override {
|
||||
int w, h;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "Chars.h"
|
||||
#include "exception.h"
|
||||
#include "Game.h"
|
||||
|
||||
template<TypeName Base> template<NewCopyable T> requires std::is_base_of_v<Base, T> && TypeName<T>
|
||||
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 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;
|
||||
Logger.log(str);
|
||||
#if __CARLBEKS_MEMORY__ > 2
|
||||
@@ -35,7 +37,7 @@ void printAllocate(void* value, size_t size, const String& msg) {
|
||||
#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;
|
||||
Logger.log(str);
|
||||
#if __CARLBEKS_MEMORY__ > 2
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <fstream>
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
|
||||
using wchar = wchar_t;
|
||||
using QWORD = unsigned long long int;
|
||||
@@ -31,7 +31,10 @@ template<typename F> using Function = std::function<F>;
|
||||
#define Success() { return 0; }
|
||||
#define Failed() { 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冲突。 */
|
||||
#if false
|
||||
#include <WinSock2.h>
|
||||
@@ -45,7 +48,6 @@ template<typename F> using Function = std::function<F>;
|
||||
#include <wingdi.h>
|
||||
#include <WinUser.h>
|
||||
#include <Uxtheme.h>
|
||||
#include <iostream>
|
||||
#include <dwmapi.h>
|
||||
|
||||
#define WM_APP_LBUTTONUP (WM_APP + 1)
|
||||
@@ -76,18 +78,19 @@ concept PointerType = std::is_pointer_v<T>;
|
||||
template<typename 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 MemoryInfo {
|
||||
std::size_t size;
|
||||
const String msg;
|
||||
std::size_t size;
|
||||
};
|
||||
|
||||
Map<void*, MemoryInfo> allocated;
|
||||
Map<void*, MemoryInfo> allocated {};
|
||||
|
||||
constexpr MemoryManager() noexcept = default;
|
||||
} inline memoryManager;
|
||||
|
||||
void requireNonnull(const void* value) noexcept(false);
|
||||
void checkAllocation(const void* value) noexcept(false);
|
||||
inline String ptrtow(QWORD value);
|
||||
|
||||
#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&);
|
||||
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);
|
||||
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
|
||||
printAllocate(value, k->second.size, k->second.msg);
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T> T* _deallocating(T* value) {
|
||||
template<typename T> T* deallocating$(T* value) {
|
||||
#if __CARLBEKS_MEMORY__ > 1
|
||||
const MemoryManager::MemoryInfo* info = nullptr;
|
||||
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
|
||||
#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
|
||||
#define allocatedFor(val, ...) _allocatedFor(val, L"" __VA_OPT__(,) __VA_ARGS__)
|
||||
#define allocatedFor(val, ...) allocatedFor$(val, L"" __VA_OPT__(,) __VA_ARGS__)
|
||||
#endif
|
||||
#define deallocating(val) _deallocating(val)
|
||||
#define deallocating(val) deallocating$(val)
|
||||
#else
|
||||
#define allocatedFor(val, ...) val
|
||||
#define deallocating(val) val
|
||||
@@ -137,14 +140,11 @@ public:
|
||||
*/
|
||||
ObjectHolder() : value(nullptr), hasValue(false) {}
|
||||
|
||||
// ReSharper disable once CppNonExplicitConvertingConstructor
|
||||
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>
|
||||
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>
|
||||
ObjectHolder(T&& value) : value(allocatedFor(new T(std::forward<T>(value)))), hasValue(true) {}
|
||||
|
||||
@@ -196,11 +196,17 @@ public:
|
||||
return *value;
|
||||
}
|
||||
|
||||
// ReSharper disable once CppNonExplicitConversionOperator
|
||||
[[nodiscard]] operator Base*() const noexcept(false) { return value; }
|
||||
Base* ptr() const noexcept { return value; }
|
||||
operator bool() const noexcept { return value; }
|
||||
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 {
|
||||
|
||||
+17
-9
@@ -23,31 +23,39 @@ class NullPointerException final : public Exception {
|
||||
inline static const String type = L"NullPointerException";
|
||||
|
||||
public:
|
||||
explicit NullPointerException(String&& msg) : Exception(std::move(msg), &type) {}
|
||||
explicit NullPointerException(const String& msg) : Exception(msg, &type) {}
|
||||
NullPointerException(String&& msg) : Exception(std::move(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 {
|
||||
inline static const String type = L"ArrayIndexOutOfBoundException";
|
||||
|
||||
public:
|
||||
explicit ArrayIndexOutOfBoundException(String&& msg) : Exception(std::move(msg), &type) {}
|
||||
explicit ArrayIndexOutOfBoundException(const String& msg) : Exception(msg, &type) {}
|
||||
ArrayIndexOutOfBoundException(String&& msg) : Exception(std::move(msg), &type) {}
|
||||
ArrayIndexOutOfBoundException(const String& msg) : Exception(msg, &type) {}
|
||||
};
|
||||
|
||||
class InvalidOperationException final : public Exception {
|
||||
inline static const String type = L"InvalidOperationException";
|
||||
|
||||
public:
|
||||
explicit InvalidOperationException(String&& msg) : Exception(std::move(msg), &type) {}
|
||||
explicit InvalidOperationException(const String& msg) : Exception(msg, &type) {}
|
||||
InvalidOperationException(String&& msg) : Exception(std::move(msg), &type) {}
|
||||
InvalidOperationException(const String& msg) : Exception(msg, &type) {}
|
||||
};
|
||||
|
||||
class RuntimeException final : public Exception {
|
||||
inline static const String type = L"RuntimeException";
|
||||
public:
|
||||
explicit RuntimeException(String&& msg) : Exception(std::move(msg), &type) {}
|
||||
explicit RuntimeException(const String& msg) : Exception(msg, &type) {}
|
||||
RuntimeException(String&& msg) : Exception(std::move(msg), &type) {}
|
||||
RuntimeException(const String& msg) : Exception(msg, &type) {}
|
||||
};
|
||||
|
||||
|
||||
@@ -68,7 +76,7 @@ class PublicLogger final {
|
||||
|
||||
public:
|
||||
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 {
|
||||
std::wcout << L"[] [Root]" + name + msg + L"\n";
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "warnings.h"
|
||||
#include "def.h"
|
||||
#include "File.h"
|
||||
|
||||
struct IGarbage;
|
||||
template <typename T>
|
||||
@@ -18,7 +20,7 @@ private:
|
||||
|
||||
protected:
|
||||
void* ptr;
|
||||
explicit IGarbage(void* ptr) : ptr(ptr) {}
|
||||
IGarbage(void* ptr) : ptr(ptr) {}
|
||||
virtual ~IGarbage() = default;
|
||||
virtual void collect() = 0;
|
||||
virtual void deleteThis() = 0;
|
||||
@@ -29,7 +31,7 @@ class Garbage final : public IGarbage {
|
||||
friend class GarbageCollector;
|
||||
|
||||
public:
|
||||
explicit Garbage(T* ptr) : IGarbage(ptr) {}
|
||||
Garbage(T* ptr) : IGarbage(ptr) {}
|
||||
void collect() override { delete static_cast<T*>(deallocating(ptr)); }
|
||||
|
||||
protected:
|
||||
@@ -44,14 +46,14 @@ class GarbageCollector {
|
||||
IGarbage* processing = nullptr;
|
||||
|
||||
public:
|
||||
GarbageCollector() = default;
|
||||
GarbageCollector() { MainLogFile << L"initialize GarbageCollector" << std::endl; }
|
||||
GarbageCollector(const GarbageCollector&) = delete;
|
||||
GarbageCollector(GarbageCollector&&) = delete;
|
||||
GarbageCollector& operator=(const GarbageCollector&) = delete;
|
||||
GarbageCollector& operator=(GarbageCollector&&) = delete;
|
||||
|
||||
~GarbageCollector() {
|
||||
IGarbage* iter = processing;
|
||||
IGarbage* iter;
|
||||
while (processing) {
|
||||
iter = processing->next;
|
||||
processing->collect();
|
||||
@@ -76,17 +78,21 @@ public:
|
||||
/** 只能在gameThread调用 */
|
||||
template <TypeName T>
|
||||
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) { // 后续添加,可能存在线程竞争
|
||||
while (end->next) end = end->next; // 理论上不会进入循环,但防止万一
|
||||
end->next = garbage;
|
||||
if (submitted) submittedEnd = garbage; // 参考pack(),submitted会被先置空
|
||||
end->next = newedGarbage;
|
||||
if (submitted) submittedEnd = newedGarbage; // 参考pack(),submitted会被先置空
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
if (!submitted) submittedEnd = nullptr; // 防止submittedEnd = garbage在pack()中置空后进行。此函数是同步的,所以可以这样操作。
|
||||
}
|
||||
else { // 添加首个,一定不会有线程竞争;或先前的已经pack
|
||||
submitted = garbage;
|
||||
submittedEnd = garbage;
|
||||
submitted = newedGarbage;
|
||||
submittedEnd = newedGarbage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +121,7 @@ public:
|
||||
|
||||
/** 只能在gameThread调用 */
|
||||
void collect() {
|
||||
IGarbage* next = processing;
|
||||
IGarbage* next;
|
||||
while (processing) {
|
||||
next = processing->next;
|
||||
processing->next = nullptr;
|
||||
@@ -140,3 +146,5 @@ public:
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline GarbageCollector& [[carlbeks::releasedat("main.cpp")]] gc = *new GarbageCollector();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
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 {
|
||||
AllocConsole();
|
||||
FILE* pCout;
|
||||
freopen_s(&pCout, "CONOUT$", "w", stdout);
|
||||
FILE* pCin;
|
||||
freopen_s(&pCin, "CONIN$", "r", stdin);
|
||||
freopen_s(&pCin, "CONOUT$", "r+", stdin);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -4,15 +4,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "warnings.h"
|
||||
|
||||
#include "def.h"
|
||||
#include "File.h"
|
||||
#include "exception.h"
|
||||
#include "gc.h"
|
||||
#include "utils.h"
|
||||
#include "hbp.h"
|
||||
#include "Chars.h"
|
||||
#include "gc.h"
|
||||
#include "Task.h"
|
||||
|
||||
#include "File.h"
|
||||
#include "Renderer.h"
|
||||
#include "Animation.h"
|
||||
#include "InteractManager.h"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "IText.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) {
|
||||
[[likely]]
|
||||
case WM_PAINT: {
|
||||
@@ -68,7 +68,7 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
renderer.windowSize = wParam;
|
||||
renderer.windowSize = static_cast<byte>(wParam);
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
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:
|
||||
if (interactManager.isInClientCaption()) {
|
||||
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;
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_NCRBUTTONDOWN:
|
||||
if (interactManager.isInClientCaption()) {
|
||||
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;
|
||||
case WM_APP_LBUTTONUP: // case WM_LBUTTONUP: case WM_NCLBUTTONUP:
|
||||
case WM_APP_LBUTTONUP:
|
||||
if (interactManager.isInClientCaption()) {
|
||||
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;
|
||||
case WM_RBUTTONUP:
|
||||
case WM_NCRBUTTONUP:
|
||||
if (interactManager.isInClientCaption()) {
|
||||
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;
|
||||
case WM_APP_MBUTTONDOWN: // case WM_MBUTTONDOWN: case WM_NCMBUTTONDOWN:
|
||||
case WM_APP_MBUTTONDOWN:
|
||||
if (interactManager.isInClientCaption()) {
|
||||
if (wParam & 0x10) interactManager.update(VK_MBUTTON, true);
|
||||
game.passEvent(MouseActionCode::MAC_DOWN, interactManager.getMouseButtonCode() | static_cast<int>(MouseButtonCodeEnum::MBC_M_CHANGE), interactManager.getMouseX(), interactManager.getMouseY());
|
||||
if (static_cast<QWORD>(wParam) & 0x10u) interactManager.update(VK_MBUTTON, true);
|
||||
game.passEvent(MouseActionCode::MAC_DOWN, interactManager.getMouseButtonCode() | static_cast<unsigned int>(MouseButtonCodeEnum::MBC_M_CHANGE), interactManager.getMouseX(), interactManager.getMouseY());
|
||||
}
|
||||
break;
|
||||
case WM_MBUTTONUP:
|
||||
case WM_NCMBUTTONUP:
|
||||
if (interactManager.isInClientCaption()) {
|
||||
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;
|
||||
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());
|
||||
break;
|
||||
case WM_DWMCOMPOSITIONCHANGED: {
|
||||
MARGINS margins{
|
||||
constexpr MARGINS margins{
|
||||
.cxLeftWidth = 0,
|
||||
.cxRightWidth = 0,
|
||||
.cyTopHeight = 0,
|
||||
.cyBottomHeight = 0
|
||||
};
|
||||
margins = { -1 };
|
||||
RemoveDefaultCaption(hwnd, &margins);
|
||||
break;
|
||||
}
|
||||
case WM_NCCALCSIZE:
|
||||
if (wParam == 1) {
|
||||
NCCALCSIZE_PARAMS* pncsp = reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam);
|
||||
pncsp->rgrc[0].left = pncsp->rgrc[0].left + 0;
|
||||
pncsp->rgrc[0].top = pncsp->rgrc[0].top + 0;
|
||||
pncsp->rgrc[0].right = pncsp->rgrc[0].right - 0;
|
||||
pncsp->rgrc[0].bottom = pncsp->rgrc[0].bottom - 0;
|
||||
NCCALCSIZE_PARAMS* params = reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam);
|
||||
params->rgrc[0].left = params->rgrc[0].left + 0;
|
||||
params->rgrc[0].top = params->rgrc[0].top + 0;
|
||||
params->rgrc[0].right = params->rgrc[0].right - 0;
|
||||
params->rgrc[0].bottom = params->rgrc[0].bottom - 0;
|
||||
renderer.resizeStart();
|
||||
return 0;
|
||||
}
|
||||
@@ -170,7 +169,7 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
return 0;
|
||||
[[unlikely]]
|
||||
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();
|
||||
break;
|
||||
default:
|
||||
@@ -179,7 +178,7 @@ LRESULT __stdcall WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM 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) {
|
||||
Logger.log(L"HookProc nCode < 0");
|
||||
return CallNextHookEx(nullptr, code, wParam, lParam);
|
||||
@@ -188,10 +187,12 @@ LRESULT __stdcall HookProc(int code, WPARAM wParam, LPARAM lParam) {
|
||||
case WM_LBUTTONUP:
|
||||
case WM_NCLBUTTONUP:
|
||||
PostMessageW(MainWindowHandle, WM_APP_LBUTTONUP, p->wParam, p->lParam);
|
||||
MainLogFile << L"BUTTON-UP\n";
|
||||
return 0;
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_NCMBUTTONDOWN:
|
||||
PostMessageW(MainWindowHandle, WM_APP_MBUTTONDOWN, p->wParam, p->lParam);
|
||||
MainLogFile << L"BUTTON-DOWN\n";
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
@@ -205,7 +206,7 @@ void gameThread() {
|
||||
using Time = time_point<system_clock>;
|
||||
Time lastTick = system_clock::now();
|
||||
while (isRunning) {
|
||||
Time thisTime = system_clock::now();
|
||||
const Time thisTime = system_clock::now();
|
||||
if (thisTime - lastTick < milliseconds(45)) {
|
||||
Sleep(1);
|
||||
continue;
|
||||
@@ -228,7 +229,7 @@ void renderThread() {
|
||||
renderer.initialize();
|
||||
Time lastRender = system_clock::now();
|
||||
while (isRunning) {
|
||||
Time thisTime = system_clock::now();
|
||||
const Time thisTime = system_clock::now();
|
||||
if (thisTime - lastRender < milliseconds(12)) {
|
||||
Sleep(1);
|
||||
continue;
|
||||
@@ -243,7 +244,8 @@ void renderThread() {
|
||||
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()); // 次序提前至最先
|
||||
for (const auto& [addr, info] : memoryManager.allocated) { Logger.print(L" using", addr, info.size, L"B", info.msg); }
|
||||
MainLogFile << L"--------Program Start--------" << std::endl;
|
||||
@@ -257,60 +259,64 @@ int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCm
|
||||
wc.hInstance = hInstance;
|
||||
wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
|
||||
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.lpszClassName = ApplicationName.c_str();
|
||||
if (!RegisterClassExW(&wc)) return FALSE;
|
||||
if (!SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) Logger.print(L"SetProcessDpiAwarenessContext failed. LastError:", GetLastError());
|
||||
MainInstance = hInstance;
|
||||
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);
|
||||
MARGINS margins{
|
||||
SetWindowLongW(MainWindowHandle, GWL_STYLE, WS_VISIBLE | WS_MAXIMIZEBOX | WS_MAXIMIZE);
|
||||
constexpr MARGINS margins{
|
||||
.cxLeftWidth = 0,
|
||||
.cxRightWidth = 0,
|
||||
.cyTopHeight = 0,
|
||||
.cyBottomHeight = 0
|
||||
};
|
||||
// margins = { -1 };
|
||||
RemoveDefaultCaption(MainWindowHandle, &margins);
|
||||
// DWM_BLURBEHIND blur{
|
||||
// .dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION | DWM_BB_TRANSITIONONMAXIMIZED,
|
||||
// .fEnable = TRUE,
|
||||
// .hRgnBlur = CreateRectRgn(0, 0, 400, 400),
|
||||
// .fTransitionOnMaximized = FALSE
|
||||
// };
|
||||
// DwmEnableBlurBehindWindow(MainWindowHandle, &blur);
|
||||
// DeleteObject(blur.hRgnBlur);
|
||||
SetWindowLongW(MainWindowHandle, GWL_EXSTYLE, GetWindowLongW(MainWindowHaTndle, GWL_EXSTYLE) | WS_EX_LAYERED);
|
||||
int a = -40;
|
||||
game.tasks.pushNewed(new Task([&a](Task& self) {
|
||||
if (a) {
|
||||
++a;
|
||||
SetLayeredWindowAttributes(MainWindowHandle, 0xffffff, static_cast<BYTE>(0xff * (40 + a) / 40), LWA_COLORKEY | LWA_ALPHA);
|
||||
} else {
|
||||
SetLayeredWindowAttributes(MainWindowHandle, 0xffffff, 0xff, LWA_COLORKEY | LWA_ALPHA);
|
||||
self.schedulePop(true);
|
||||
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);
|
||||
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();
|
||||
}
|
||||
SetConsoleOutputCP(65001);
|
||||
HHOOK hook = SetWindowsHookW(WH_GETMESSAGE, HookProc);
|
||||
test();
|
||||
HACCEL hAccelTable = LoadAcceleratorsW(hInstance, MAKEINTRESOURCE(109));
|
||||
MSG msg = { nullptr };
|
||||
GameThread = Thread(gameThread);
|
||||
RenderThread = Thread(renderThread);
|
||||
}
|
||||
MSG msg = { nullptr };
|
||||
while (GetMessageW(&msg, nullptr, 0, 0)) {
|
||||
if (!TranslateAcceleratorW(msg.hwnd, hAccelTable, &msg)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
}
|
||||
{
|
||||
isRunning = false;
|
||||
if (GameThread.joinable()) GameThread.join();
|
||||
if (RenderThread.joinable()) RenderThread.join();
|
||||
}
|
||||
DestroyAcceleratorTable(hAccelTable);
|
||||
UnhookWindowsHookEx(hook);
|
||||
_wsystem(L"pause");
|
||||
for (const auto& [addr, info] : memoryManager.allocated) { Logger.print(L"using", addr, info.size, L"B", info.msg); }
|
||||
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; }
|
||||
_wsystem(L"pause");
|
||||
_wsystem(L"pause");
|
||||
return static_cast<int>(msg.wParam);
|
||||
}
|
||||
|
||||
@@ -318,9 +324,10 @@ struct Release {
|
||||
Release() = default;
|
||||
|
||||
~Release() {
|
||||
delete &gc;
|
||||
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; }
|
||||
MainLogFile.close();
|
||||
delete &MainLogFile;
|
||||
}
|
||||
} x;
|
||||
} NEVER_REFERENCED_release;
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
//
|
||||
// Created by EmsiaetKadosh on 25-3-4.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gc.h"
|
||||
|
||||
template <typename T, typename L = void>
|
||||
class AnywhereEditable;
|
||||
template <typename T, typename L = void>
|
||||
@@ -11,6 +14,7 @@ template <typename T, typename L = void>
|
||||
class AnywhereIterator;
|
||||
class AnywhereIteratorEnd;
|
||||
|
||||
|
||||
/**
|
||||
* 此处无法进行代码编译层面的直接约束
|
||||
* @tparam T 满足T extends AnywhereEditable<T, L>
|
||||
@@ -33,9 +37,8 @@ private:
|
||||
public:
|
||||
byte reserved[7]{}; // reserved[0]: Task::schedulePop
|
||||
|
||||
public:
|
||||
AnywhereEditable() = default;
|
||||
AnywhereEditable(const AnywhereEditable& other) {}
|
||||
AnywhereEditable(const AnywhereEditable&) {}
|
||||
|
||||
AnywhereEditable(AnywhereEditable&& other) noexcept : prev(other->prev), next(other->next), list(other->list) {
|
||||
other->prev = nullptr;
|
||||
@@ -65,7 +68,7 @@ class AnywhereIterator {
|
||||
AnywhereEditable<T, L>* current;
|
||||
|
||||
public:
|
||||
explicit AnywhereIterator(AnywhereEditable<T, L>* current) : current(current) {}
|
||||
AnywhereIterator(AnywhereEditable<T, L>* current) : current(current) {}
|
||||
AnywhereIterator(const AnywhereIterator& other) = default;
|
||||
|
||||
T& operator*() noexcept(false) {
|
||||
@@ -116,7 +119,7 @@ public:
|
||||
|
||||
class AnywhereIteratorEnd {
|
||||
public:
|
||||
AnywhereIteratorEnd() {}
|
||||
AnywhereIteratorEnd() = default;
|
||||
AnywhereIteratorEnd(const 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)); }
|
||||
|
||||
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>
|
||||
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->next->prev = value->prev;
|
||||
value->prev->next = value->next;
|
||||
if (value->managedByList) delete deallocating(value);
|
||||
if (value->managedByList) gc.submit(value);
|
||||
Success();
|
||||
}
|
||||
|
||||
@@ -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
@@ -8,28 +8,42 @@
|
||||
|
||||
class StartWindow final : public Window {
|
||||
TranslatableText title = TranslatableText(L"hbp.title");
|
||||
|
||||
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());
|
||||
start->onTick = [start, this](int) { if (start->containsMouse()) game.getFloatWindow().push(L"\\#ff44ee66退出游戏"_renderable); };
|
||||
start->mouseUp = [](int) {
|
||||
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 = [](const Widget& self, MouseButtonCode) { if (self.containsMouse()) game.getFloatWindow().push(L"\\#ff44ee66退出游戏"_renderable); };
|
||||
start->mouseClick = [](Widget&, MouseButtonCode) {
|
||||
game.setWindow(&ConfirmWindow::of(LiteralText(L"是否\\#ff44ee66退出游戏\\r?"))->requireCancel().requireConfirm([](Button& confirm) {
|
||||
confirm.mouseUp = [](int) { DestroyWindow(MainWindowHandle); };
|
||||
confirm.onTick = [&confirm](int) {
|
||||
if (confirm.containsMouse()) {
|
||||
confirm.mouseClick = [](Widget&, MouseButtonCode) { DestroyWindow(MainWindowHandle); };
|
||||
confirm.onTick = [](Widget& self, MouseButtonCode) {
|
||||
if (self.containsMouse()) {
|
||||
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:
|
||||
static StartWindow* create() noexcept { return allocatedFor(new StartWindow()); }
|
||||
void onClose() override { pop(); }
|
||||
|
||||
void render() const noexcept override {
|
||||
fontManager.getDefault().drawCenter(title.getRenderableString(), 0, 0, renderer.getWidth(), renderer.getHeight());
|
||||
Window::render();
|
||||
|
||||
Reference in New Issue
Block a user