aa
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include <actor.hpp>
|
||||
|
||||
namespace openceg::render {
|
||||
|
||||
struct InputEvent {
|
||||
enum class Type {
|
||||
Key,
|
||||
MouseButton,
|
||||
CursorMove,
|
||||
Scroll,
|
||||
};
|
||||
|
||||
enum class Action {
|
||||
Release = 0,
|
||||
Press = 1,
|
||||
Repeat = 2,
|
||||
};
|
||||
|
||||
Type type = Type::Key;
|
||||
Action action = Action::Press;
|
||||
int key = -1;
|
||||
int scancode = -1;
|
||||
int mods = 0;
|
||||
int button = -1;
|
||||
double x = 0.0;
|
||||
double y = 0.0;
|
||||
};
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
Renderer();
|
||||
~Renderer();
|
||||
|
||||
Renderer(const Renderer&) = delete;
|
||||
Renderer& operator=(const Renderer&) = delete;
|
||||
Renderer(Renderer&&) = delete;
|
||||
Renderer& operator=(Renderer&&) = delete;
|
||||
|
||||
void init(int width, int height, const char* title);
|
||||
void draw(const Actor* const* actors, size_t actor_count);
|
||||
bool should_close() const;
|
||||
void poll_events() const;
|
||||
|
||||
using InputCallback = std::function<void(const InputEvent&)>;
|
||||
void set_input_callback(InputCallback callback);
|
||||
|
||||
bool is_key_down(int key) const;
|
||||
bool is_mouse_button_down(int button) const;
|
||||
std::array<double, 2> cursor_position() const;
|
||||
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
Impl* impl_;
|
||||
};
|
||||
|
||||
// 类似 Godot InputMap 的按键动作绑定。
|
||||
class InputMap {
|
||||
public:
|
||||
void add_action(const std::string& action);
|
||||
void bind_key(const std::string& action, int key);
|
||||
void unbind_key(const std::string& action, int key);
|
||||
void bind_mouse_button(const std::string& action, int button);
|
||||
void unbind_mouse_button(const std::string& action, int button);
|
||||
|
||||
void handle_event(const InputEvent& event);
|
||||
void end_frame();
|
||||
|
||||
bool is_action_pressed(const std::string& action) const;
|
||||
bool is_action_just_pressed(const std::string& action) const;
|
||||
bool is_action_just_released(const std::string& action) const;
|
||||
float get_action_strength(const std::string& action) const;
|
||||
float get_axis(const std::string& negative_action,
|
||||
const std::string& positive_action) const;
|
||||
|
||||
private:
|
||||
struct ActionState {
|
||||
std::unordered_set<int> keys;
|
||||
std::unordered_set<int> mouse_buttons;
|
||||
std::unordered_map<int, bool> held_keys;
|
||||
std::unordered_map<int, bool> held_buttons;
|
||||
size_t held_key_count = 0;
|
||||
size_t held_button_count = 0;
|
||||
bool pressed = false;
|
||||
bool just_pressed = false;
|
||||
bool just_released = false;
|
||||
};
|
||||
|
||||
mutable std::mutex mutex_;
|
||||
std::unordered_map<std::string, ActionState> actions_;
|
||||
};
|
||||
|
||||
// 渲染线程包装:主线程更新 Actor,渲染线程持续读取并提交绘制。
|
||||
class RenderLoop {
|
||||
public:
|
||||
RenderLoop() = default;
|
||||
~RenderLoop();
|
||||
|
||||
RenderLoop(const RenderLoop&) = delete;
|
||||
RenderLoop& operator=(const RenderLoop&) = delete;
|
||||
RenderLoop(RenderLoop&&) = delete;
|
||||
RenderLoop& operator=(RenderLoop&&) = delete;
|
||||
|
||||
void start(int width, int height, const char* title);
|
||||
void stop();
|
||||
|
||||
void set_actors(std::vector<Actor*> actors);
|
||||
void poll_events() const;
|
||||
bool should_close() const;
|
||||
|
||||
InputMap& input();
|
||||
const InputMap& input() const;
|
||||
|
||||
private:
|
||||
void run();
|
||||
|
||||
Renderer renderer_;
|
||||
InputMap input_map_;
|
||||
std::thread thread_;
|
||||
std::atomic<bool> running_{false};
|
||||
mutable std::mutex actors_mutex_;
|
||||
std::vector<Actor*> actors_;
|
||||
};
|
||||
|
||||
} // namespace openceg::render
|
||||
Reference in New Issue
Block a user