Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Application singleton now uses protected constructor and logic_error check

### Fixed

- Fix window ownership and event bus safety

## [0.6.0] - 2026-02-15

- Change headers parent folder to Kappa
Expand Down
2 changes: 1 addition & 1 deletion include/Kappa/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ namespace Kappa
private:
ApplicationSpecification specification; ///< Application configuration
std::vector<std::unique_ptr<Layer>> layerStack; ///< Stack of application layers
std::shared_ptr<Window> window; ///< Main application window
std::unique_ptr<Window> window; ///< Main application window
bool isRunning = false; ///< Flag indicating if the application is running
EventBus eventBus; ///< Event bus for inter-layer communication
};
Expand Down
25 changes: 20 additions & 5 deletions include/Kappa/EventBus.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <functional>
#include <memory>
#include <mutex>
#include <typeindex>
#include <unordered_map>
#include <vector>
Expand All @@ -25,8 +26,14 @@ namespace Kappa
requires std::is_base_of_v<Event, TEvent>
void Subscribe(std::function<void(const TEvent &)> callback)
{
std::lock_guard<std::mutex> lock(subscribersMutex);
const auto typeIndex = std::type_index(typeid(TEvent));
auto wrapper = [callback](const Event &event) { callback(static_cast<const TEvent &>(event)); };
auto wrapper = [callback](const Event &event) {
if (const auto *specEvent = dynamic_cast<const TEvent *>(&event))
{
callback(*specEvent);
}
};
subscribers[typeIndex].push_back(wrapper);
}

Expand All @@ -39,26 +46,34 @@ namespace Kappa
requires std::is_base_of_v<Event, TEvent>
void Publish(const TEvent &event)
{
const auto typeIndex = std::type_index(typeid(TEvent));
if (const auto it = subscribers.find(typeIndex); it != subscribers.end())
std::vector<EventCallback> handlers;
{
for (const auto &callback : it->second)
std::lock_guard<std::mutex> lock(subscribersMutex);
const auto typeIndex = std::type_index(typeid(TEvent));
if (const auto it = subscribers.find(typeIndex); it != subscribers.end())
{
callback(event);
handlers = it->second;
}
}

for (const auto &callback : handlers)
{
callback(event);
}
}

/**
* @brief Clears all subscribers.
*/
void Clear()
{
std::lock_guard<std::mutex> lock(subscribersMutex);
subscribers.clear();
}

private:
using EventCallback = std::function<void(const Event &)>;
std::unordered_map<std::type_index, std::vector<EventCallback>> subscribers;
mutable std::mutex subscribersMutex;
};
} // namespace Kappa
2 changes: 1 addition & 1 deletion src/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace Kappa
specification.windowSpecification.title = specification.name;
}

window = std::make_shared<Window>(specification.windowSpecification);
window = std::make_unique<Window>(specification.windowSpecification);
window->Create();
}

Expand Down
Loading