Iniciando un buen sistema de callbacks!

This commit is contained in:
2025-06-26 20:59:49 -04:00
parent b186b25a9c
commit 4d129018e3
10 changed files with 151 additions and 57 deletions

1
.idea/editor.xml generated
View File

@@ -117,6 +117,7 @@
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMismatchedClassTags/@EntryIndexedValue" value="WARNING" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMismatchedClassTags/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingIncludeGuard/@EntryIndexedValue" value="WARNING" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingIncludeGuard/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingKeywordThrow/@EntryIndexedValue" value="WARNING" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingKeywordThrow/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppModulePartitionWithSeveralPartitionUnits/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtAddressOfClassRValue/@EntryIndexedValue" value="WARNING" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtAddressOfClassRValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtBindingRValueToLvalueReference/@EntryIndexedValue" value="WARNING" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtBindingRValueToLvalueReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtCopyElisionInCopyInitDeclarator/@EntryIndexedValue" value="WARNING" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtCopyElisionInCopyInitDeclarator/@EntryIndexedValue" value="WARNING" type="string" />

View File

@@ -1,15 +1,30 @@
add_executable(${PROJECT_NAME}) add_executable(${PROJECT_NAME})
file(GLOB CHIP8_SOURCES "*.cpp" "**/*.cpp")
file(GLOB CHIP8_HEADERS "*.h" "**/*.h")
message(CHIP8_SOURCES="${CHIP8_SOURCES}")
message(CHIP8_HEADERS="${CHIP8_HEADERS}")
target_sources( target_sources(
${PROJECT_NAME} ${PROJECT_NAME}
PRIVATE PRIVATE
${CHIP8_SOURCES} main.cpp
${CHIP8_HEADERS} Machine.cpp
Machine.h
Graphics/Graphics.cpp
Graphics/Graphics.h
Graphics/Color.h
Interpreter/Interpreter.cpp
Interpreter/Interpreter.h
Interpreter/Instruction.h
Interpreter/MachineState.cpp
Interpreter/MachineState.h
Interpreter/OpCode.h
UI/CallbackManager.cpp
UI/CallbackManager.h
UI/ControlPanel.cpp
UI/ControlPanel.h
UI/Display.cpp
UI/Display.h
UI/UIManager.cpp
UI/UIManager.h
) )
add_compile_options(-Wall -Wextra -Wpedantic -Werror)
target_link_libraries(${PROJECT_NAME} PRIVATE vendor) target_link_libraries(${PROJECT_NAME} PRIVATE vendor)

View File

@@ -1,6 +1,8 @@
#include "Machine.h" #include "Machine.h"
#include <fstream>
#include <iostream> #include <iostream>
#include <iterator>
#include <bits/ostream.tcc> #include <bits/ostream.tcc>
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
@@ -11,31 +13,21 @@
#include "imgui_impl_sdl3.h" #include "imgui_impl_sdl3.h"
Machine::Machine(): Machine::Machine() :
machine_state{std::make_shared<MachineState>()}, machine_state{std::make_shared<MachineState>()},
graphics{std::make_shared<Graphics>()}, graphics{std::make_shared<Graphics>()},
callback_manager(std::make_shared<CallbackManager>()),
interpreter{std::make_unique<Interpreter>(this->machine_state)}, interpreter{std::make_unique<Interpreter>(this->machine_state)},
ui_manager{std::make_unique<UIManager>(this->graphics, this->machine_state)}, ui_manager{std::make_unique<UIManager>(this->graphics, this->machine_state, this->callback_manager)},
ips{700}, ips{700},
last_update_time{0}, last_update_time{0},
accumulator{0}, accumulator{0},
target_cycle_time{1.0 / this->ips} { target_cycle_time{1.0 / this->ips} {
this->register_callbacks();
ui_manager->control_panel->set_rom_load_callback(std::bind(
&Machine::on_rom_load,
this,
std::placeholders::_1
));
ui_manager->control_panel->set_reset_callback(std::bind(
&Machine::on_reset,
this
));
} }
void Machine::iterate() { void Machine::iterate() {
this->execute_interpreter(); this->execute_interpreter();
@@ -66,9 +58,43 @@ void Machine::execute_interpreter() {
} }
} }
void Machine::on_rom_load(const std::string& path) const { void Machine::register_callbacks() {
std::cout << path << std::endl; callback_manager->set_rom_load_callback(std::bind(
&Machine::on_rom_load,
this,
std::placeholders::_1
));
callback_manager->set_reset_callback(std::bind(
&Machine::on_reset,
this
));
} }
void Machine::on_rom_load(const std::string& path) const {
std::ifstream file(path, std::ios::binary);
file.unsetf(std::ios::skipws);
file.seekg(0, std::ios::end);
const std::streampos file_size = file.tellg();
file.seekg(0, std::ios::beg);
// La memoria para los rom es desde 0x200 hasta el final de 0x1000
// Por lo que un rom sería muy grande si sobrepasa este tamaño
if (file_size >= 0x1000 - 0x200 ) {
std::cout << "File too large!" << std::endl;
return;
}
this->machine_state->reset();
std::copy(
std::istream_iterator<uint8_t>(file),
std::istream_iterator<uint8_t>(),
this->machine_state->memory.begin() + 0x200
);
std::cout << "Cargado rom: " << path << std::endl;
}
void Machine::on_reset() const { void Machine::on_reset() const {
this->machine_state->reset(); this->machine_state->reset();
} }

View File

@@ -10,6 +10,7 @@
class Machine { class Machine {
std::shared_ptr<MachineState> machine_state; std::shared_ptr<MachineState> machine_state;
std::shared_ptr<Graphics> graphics; std::shared_ptr<Graphics> graphics;
std::shared_ptr<CallbackManager> callback_manager;
std::unique_ptr<Interpreter> interpreter; std::unique_ptr<Interpreter> interpreter;
std::unique_ptr<UIManager> ui_manager; std::unique_ptr<UIManager> ui_manager;
@@ -24,6 +25,7 @@ class Machine {
void on_reset() const; void on_reset() const;
public: public:
void register_callbacks();
Machine(); Machine();
void iterate(); void iterate();
bool on_event(const SDL_Event* event) const; bool on_event(const SDL_Event* event) const;

View File

@@ -0,0 +1,19 @@
#include "CallbackManager.h"
void CallbackManager::set_rom_load_callback(const RomLoadCallback& callback) {
this->rom_load_callback = callback;
}
void CallbackManager::set_reset_callback(const ResetCallback& callback) {
this->reset_callback = callback;
}
void CallbackManager::trigger_rom_load(const std::string& path) {
if (this->rom_load_callback) {
this->rom_load_callback(path);
}
}
void CallbackManager::trigger_reset() {
if (this->reset_callback) {
this->reset_callback();
}
}

24
src/UI/CallbackManager.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef CALLBACKMANAGER_H
#define CALLBACKMANAGER_H
#include <functional>
#include <string>
struct CallbackManager {
using RomLoadCallback = std::function<void(const std::string&)>;
using ResetCallback = std::function<void()>;
void set_rom_load_callback(const RomLoadCallback& callback);
void set_reset_callback(const ResetCallback& callback);
void trigger_rom_load(const std::string& path);
void trigger_reset();
private:
RomLoadCallback rom_load_callback;
ResetCallback reset_callback;
};
#endif //CALLBACKMANAGER_H

View File

@@ -1,22 +1,18 @@
#include "ControlPanel.h" #include "ControlPanel.h"
#include <format> #include <format>
#include <ranges>
#include "imgui.h" #include "imgui.h"
ControlPanel::ControlPanel( ControlPanel::ControlPanel(
std::shared_ptr<Graphics> graphics, std::shared_ptr<Graphics> graphics,
std::shared_ptr<MachineState> machine_state std::shared_ptr<MachineState> machine_state,
): graphics{std::move(graphics)}, std::shared_ptr<CallbackManager> callback_manager
machine_state{std::move(machine_state)} {} ) : graphics{std::move(graphics)},
machine_state{std::move(machine_state)},
void ControlPanel::set_rom_load_callback(const std::function<void(std::string)>& callback) { callback_manager{std::move(callback_manager)} {}
this->rom_load_callback = callback;
}
void ControlPanel::set_reset_callback(const std::function<void()>& callback) {
this->reset_callback = callback;
}
void ControlPanel::render() { void ControlPanel::render() {
constexpr auto full_width = ImVec2(-FLT_MIN, 0.0f); constexpr auto full_width = ImVec2(-FLT_MIN, 0.0f);
@@ -50,9 +46,7 @@ void ControlPanel::render() {
ImGui::SeparatorText(""); ImGui::SeparatorText("");
if (ImGui::Button("Reset", full_width)) { if (ImGui::Button("Reset", full_width)) {
if (this->reset_callback) { this->callback_manager->trigger_reset();
this->reset_callback();
}
} }
ImGui::Button("Reload ROM", full_width); ImGui::Button("Reload ROM", full_width);
} }
@@ -66,19 +60,23 @@ void ControlPanel::on_click_load_rom() {
{"All files", "*"} {"All files", "*"}
}; };
SDL_ShowOpenFileDialog(on_callback_load_rom, this, graphics->get_window().get(), filters, std::size(filters), nullptr, false); SDL_ShowOpenFileDialog(
on_callback_load_rom,
this,
graphics->get_window().get(),
filters,
std::size(filters),
SDL_GetCurrentDirectory(),
false
);
} }
void ControlPanel::on_callback_load_rom(void* userdata, const char* const* filelist, int filter) { void ControlPanel::on_callback_load_rom(void* self, const char* const* filelist, int filter) {
const auto control_panel = static_cast<ControlPanel*>(userdata); const auto control_panel = static_cast<ControlPanel*>(self);
if (!control_panel->rom_load_callback) {
return;
}
if (!filelist || !*filelist) { if (!filelist || !*filelist) {
return; return;
} }
control_panel->rom_load_callback(*filelist); control_panel->callback_manager->trigger_rom_load(filelist[0]);
} }

View File

@@ -2,7 +2,9 @@
#define CONTROLPANEL_H #define CONTROLPANEL_H
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <variant>
#include "CallbackManager.h"
#include "../Graphics/Graphics.h" #include "../Graphics/Graphics.h"
#include "../Interpreter/MachineState.h" #include "../Interpreter/MachineState.h"
@@ -10,25 +12,21 @@
class ControlPanel { class ControlPanel {
std::shared_ptr<Graphics> graphics; std::shared_ptr<Graphics> graphics;
std::shared_ptr<MachineState> machine_state; std::shared_ptr<MachineState> machine_state;
std::shared_ptr<CallbackManager> callback_manager;
bool run = false; bool run = false;
int steps = 1; int steps = 1;
int speed = 100; int speed = 100;
std::function<void(std::string)> rom_load_callback; static SDLCALL void on_callback_load_rom(void* self, const char* const* filelist, int filter);
std::function<void()> reset_callback;
static SDLCALL void on_callback_load_rom(void* userdata, const char* const* filelist, int filter);
public: public:
ControlPanel( ControlPanel(
std::shared_ptr<Graphics> graphics, std::shared_ptr<Graphics> graphics,
std::shared_ptr<MachineState> machine_state std::shared_ptr<MachineState> machine_state,
std::shared_ptr<CallbackManager> callback_manager
); );
void set_rom_load_callback(const std::function<void(std::string)>& callback);
void set_reset_callback(const std::function<void()>& callback);
void render(); void render();
void on_click_load_rom(); void on_click_load_rom();
}; };

View File

@@ -1,10 +1,15 @@
#include "UIManager.h" #include "UIManager.h"
UIManager::UIManager(std::shared_ptr<Graphics> graphics, std::shared_ptr<MachineState> machine_state): UIManager::UIManager(
std::shared_ptr<Graphics> graphics,
std::shared_ptr<MachineState> machine_state,
std::shared_ptr<CallbackManager> callback_manager
) :
graphics{std::move(graphics)}, graphics{std::move(graphics)},
machine_state{std::move(machine_state)}, machine_state{std::move(machine_state)},
callback_manager{std::move(callback_manager)},
display{std::make_unique<Display>(this->graphics, this->machine_state)}, display{std::make_unique<Display>(this->graphics, this->machine_state)},
control_panel{std::make_unique<ControlPanel>(this->graphics, this->machine_state)} {} control_panel{std::make_unique<ControlPanel>(this->graphics, this->machine_state, this->callback_manager)} {}
void UIManager::render() { void UIManager::render() {
this->display->render(); this->display->render();

View File

@@ -2,6 +2,7 @@
#define UIMANAGER_H #define UIMANAGER_H
#include <memory> #include <memory>
#include "CallbackManager.h"
#include "ControlPanel.h" #include "ControlPanel.h"
#include "Display.h" #include "Display.h"
#include "../Graphics/Graphics.h" #include "../Graphics/Graphics.h"
@@ -9,12 +10,17 @@
class UIManager { class UIManager {
std::shared_ptr<Graphics> graphics; std::shared_ptr<Graphics> graphics;
std::shared_ptr<MachineState> machine_state; std::shared_ptr<MachineState> machine_state;
std::shared_ptr<CallbackManager> callback_manager;
public: public:
std::unique_ptr<Display> display; std::unique_ptr<Display> display;
std::unique_ptr<ControlPanel> control_panel; std::unique_ptr<ControlPanel> control_panel;
public: UIManager(
UIManager(std::shared_ptr<Graphics> graphics, std::shared_ptr<MachineState> machine_state); std::shared_ptr<Graphics> graphics,
std::shared_ptr<MachineState> machine_state,
std::shared_ptr<CallbackManager> callback_manager
);
void render() ; void render() ;
}; };