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/=CppMissingIncludeGuard/@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/=CppMsExtBindingRValueToLvalueReference/@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})
file(GLOB CHIP8_SOURCES "*.cpp" "**/*.cpp")
file(GLOB CHIP8_HEADERS "*.h" "**/*.h")
message(CHIP8_SOURCES="${CHIP8_SOURCES}")
message(CHIP8_HEADERS="${CHIP8_HEADERS}")
target_sources(
${PROJECT_NAME}
PRIVATE
${CHIP8_SOURCES}
${CHIP8_HEADERS}
main.cpp
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)

View File

@@ -1,6 +1,8 @@
#include "Machine.h"
#include <fstream>
#include <iostream>
#include <iterator>
#include <bits/ostream.tcc>
#include "Graphics/Graphics.h"
@@ -14,28 +16,18 @@
Machine::Machine() :
machine_state{std::make_shared<MachineState>()},
graphics{std::make_shared<Graphics>()},
callback_manager(std::make_shared<CallbackManager>()),
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},
last_update_time{0},
accumulator{0},
target_cycle_time{1.0 / this->ips} {
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
));
this->register_callbacks();
}
void Machine::iterate() {
this->execute_interpreter();
@@ -66,9 +58,43 @@ void Machine::execute_interpreter() {
}
}
void Machine::on_rom_load(const std::string& path) const {
std::cout << path << std::endl;
void Machine::register_callbacks() {
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 {
this->machine_state->reset();
}

View File

@@ -10,6 +10,7 @@
class Machine {
std::shared_ptr<MachineState> machine_state;
std::shared_ptr<Graphics> graphics;
std::shared_ptr<CallbackManager> callback_manager;
std::unique_ptr<Interpreter> interpreter;
std::unique_ptr<UIManager> ui_manager;
@@ -24,6 +25,7 @@ class Machine {
void on_reset() const;
public:
void register_callbacks();
Machine();
void iterate();
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 <format>
#include <ranges>
#include "imgui.h"
ControlPanel::ControlPanel(
std::shared_ptr<Graphics> graphics,
std::shared_ptr<MachineState> machine_state
std::shared_ptr<MachineState> machine_state,
std::shared_ptr<CallbackManager> callback_manager
) : graphics{std::move(graphics)},
machine_state{std::move(machine_state)} {}
void ControlPanel::set_rom_load_callback(const std::function<void(std::string)>& callback) {
this->rom_load_callback = callback;
}
void ControlPanel::set_reset_callback(const std::function<void()>& callback) {
this->reset_callback = callback;
}
machine_state{std::move(machine_state)},
callback_manager{std::move(callback_manager)} {}
void ControlPanel::render() {
constexpr auto full_width = ImVec2(-FLT_MIN, 0.0f);
@@ -50,9 +46,7 @@ void ControlPanel::render() {
ImGui::SeparatorText("");
if (ImGui::Button("Reset", full_width)) {
if (this->reset_callback) {
this->reset_callback();
}
this->callback_manager->trigger_reset();
}
ImGui::Button("Reload ROM", full_width);
}
@@ -66,19 +60,23 @@ void ControlPanel::on_click_load_rom() {
{"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) {
const auto control_panel = static_cast<ControlPanel*>(userdata);
if (!control_panel->rom_load_callback) {
return;
}
void ControlPanel::on_callback_load_rom(void* self, const char* const* filelist, int filter) {
const auto control_panel = static_cast<ControlPanel*>(self);
if (!filelist || !*filelist) {
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
#include <functional>
#include <memory>
#include <variant>
#include "CallbackManager.h"
#include "../Graphics/Graphics.h"
#include "../Interpreter/MachineState.h"
@@ -10,25 +12,21 @@
class ControlPanel {
std::shared_ptr<Graphics> graphics;
std::shared_ptr<MachineState> machine_state;
std::shared_ptr<CallbackManager> callback_manager;
bool run = false;
int steps = 1;
int speed = 100;
std::function<void(std::string)> rom_load_callback;
std::function<void()> reset_callback;
static SDLCALL void on_callback_load_rom(void* userdata, const char* const* filelist, int filter);
static SDLCALL void on_callback_load_rom(void* self, const char* const* filelist, int filter);
public:
ControlPanel(
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 on_click_load_rom();
};

View File

@@ -1,10 +1,15 @@
#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)},
machine_state{std::move(machine_state)},
callback_manager{std::move(callback_manager)},
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() {
this->display->render();

View File

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