{"id":21252675,"url":"https://github.com/atomicptr/dove","last_synced_at":"2025-03-15T05:40:57.611Z","repository":{"id":257232735,"uuid":"851534521","full_name":"atomicptr/dove","owner":"atomicptr","description":"A tiny, single file, header only messaging system for games written in C++23","archived":false,"fork":false,"pushed_at":"2025-02-23T08:28:36.000Z","size":27,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-07T00:37:43.944Z","etag":null,"topics":["cpp","cpp23","game-development","header-only","header-only-library","message-broker","message-passing"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"0bsd","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/atomicptr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-03T09:16:44.000Z","updated_at":"2025-02-23T08:28:40.000Z","dependencies_parsed_at":"2024-09-15T12:58:51.996Z","dependency_job_id":"cee4e439-7094-41e3-b684-292994bf1437","html_url":"https://github.com/atomicptr/dove","commit_stats":null,"previous_names":["atomicptr/dove"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicptr%2Fdove","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicptr%2Fdove/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicptr%2Fdove/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicptr%2Fdove/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atomicptr","download_url":"https://codeload.github.com/atomicptr/dove/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243690124,"owners_count":20331726,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","cpp23","game-development","header-only","header-only-library","message-broker","message-passing"],"created_at":"2024-11-21T03:48:24.800Z","updated_at":"2025-03-15T05:40:57.582Z","avatar_url":"https://github.com/atomicptr.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dove\n\nA tiny, single file, header only messaging system for games written in C++23\n\nInspired by [pidgeon](https://github.com/atomicptr/pidgeon).\n\n## Usage\n\nDove utilizes a broker to whom you send pre defined messages with data, which you put into a queue and then process them all at once.\n\nFirst we need to define out message and data types:\n\n```cpp\n#pragma once\n\n// This file could be src/game/broker.hpp or something\n// Generally we want this at a place where it can actually be\n// included and reused\n\n#include \u003cdove/dove.hpp\u003e\n\n// In this example we will update our UI via messages, so when these values\n// changei we will send out a message\nenum class Message {\n    PlayerHPUpdated,\n    PlayerManaUpdated,\n};\n\n// for this example we will only pass new values so a number\n// is sufficient, normally you'd probably use a union or a std::variant here\nusing MessageData = unsigned int;\n\n// its highly recommended to define a Broker type like this:\nusing MyBroker = dove::Broker\u003cMessage, MessageData\u003e;\n\n// also we only want one global broker in this case:\nMyBroker* broker = nullptr;\n````\n\nNext we need to initialize the broker somewhere, for this example we just do it in main:\n\n```cpp\nint main() {\n    broker = new MyBroker;\n\n    // do stuff\n\n    delete broker;\n}\n```\n\nNow at various locations in the code we can post messages:\n\n```cpp\n#include \"broker.hpp\"\n\n// ...\n\nvoid game::Player::cast_spell(const Spell\u0026 spell) {\n    mana_amount -= spell.cost;\n\n    broker-\u003epost(Message::PlayerManaUpdated, mana_amount);\n\n    spawn_spell(spell, position, direction);\n}\n```\n\nAnd lastly we need to register to receive messages, which we can do like this:\n\n```cpp\n#include \"broker.hpp\"\n\ngame::UI::UI() {\n    // since we use a class here we need to wrap the on message handler so that we can just handle\n    // events in a class context\n    auto fn = [this](MyBroker::WhoPtr _receiver, Message message_type, MessageData message_data) {\n        return this-\u003eon_message(message_type, message_data);\n    };\n\n    // now we register the listeners\n    broker-\u003eadd_listener(Message::PlayerHPUpdated, this, fn);\n    broker-\u003eadd_listener(Message::PlayerManaUpdated, this, fn);\n}\n\n// we need to return if we handled the message or not, this helps figuring out\n// if you registered to something without handling it\nbool game::UI::on_message(Message message_type, MessageData message_data) {\n    switch (message_type) {\n    case Message::PlayerHPUpdated:\n        set_hp(message_data);\n        return true;\n    case Message::PlayerManaUpdated:\n        set_mana(message_data);\n        return true;\n    }\n\n    // in thsi case we haven't handled anything so we return false\n    return false;\n}\n```\n\nAnd thats how you use dove.\n\n## Configuration\n\nDove has a few configuration options exposed via defines.\n\nSince C++ still does not offer proper reflection (and we can't print arbitrary things), you will probably have to implement custom formatters for your Message and MessageData types\n\n### DOVE_DEBUG\n\nEnables dove to print debugging information like messages registered, messages posted, etc.\n\n```cpp\n// enable like this before you import dove\n#define DOVE_DEBUG\n```\n\n### DOVE_DEBUG_PRINT_FUNC\n\nThe function called to be when debug prints happen, defaults to std::println\n\n```cpp\n#define DOVE_DEBUG_PRINT_FUNC std::println\n````\n\n### DOVE_WARN_PRINT_FUNC\n\nThe function called to be when warning prints happen, defaults to std::println\n\n```cpp\n#define DOVE_WARN_PRINT_FUNC std::println\n````\n\n### DOVE_ERR_PRINT_FUNC\n\nThe function called to be when error prints happen, defaults to std::println (to stderr)\n\n```cpp\n#define DOVE_ERR_PRINT_FUNC std::println\n````\n\n### DOVE_ASSERT_FUNC\n\nThe function/macro called for asserts, defaults to slightly modified [rapture](https://github.com/atomicptr/rapture) assert\n\n```cpp\n#define DOVE_ASSERT(condition, ...)                                      \\\n    if (!(condition)) {                                                  \\\n        auto rapture_loc = std::source_location::current();              \\\n        DOVE_ERR_PRINT_FUNC(\"\");                                         \\\n        DOVE_ERR_PRINT_FUNC(                                             \\\n            \"========= ASSERTATION FAILED {}:{}:{} =========\",           \\\n            rapture_loc.file_name(),                                     \\\n            rapture_loc.line(),                                          \\\n            rapture_loc.column()                                         \\\n        );                                                               \\\n        DOVE_ERR_PRINT_FUNC(\"\\tAssert :\\t{}\", (#condition));             \\\n        DOVE_ERR_PRINT_FUNC(\"\\tMessage:\\t{}\", std::format(__VA_ARGS__)); \\\n        DOVE_ERR_PRINT_FUNC(\"\");                                         \\\n        std::abort();                                                    \\\n    }\n```\n\n### DOVE_DISABLE_SOURCE_LOCATION_FORMATTER\n\nBy default dove registers a std::formatter for std::source_location, but you might not want this (or a custom one) so define this to disable it\n\n### License\n\nBSD 0-Clause\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatomicptr%2Fdove","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatomicptr%2Fdove","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatomicptr%2Fdove/lists"}