VoltMod
C++23 framework for CS2 server plugins
Loading...
Searching...
No Matches
ServiceExchange.hpp
Go to the documentation of this file.
1#pragma once
2
5#include <string>
6#include <string_view>
7
8namespace VoltMod
9{
10
11/**
12 * @brief Typed view of the host's table of interfaces plugins publish to each other.
13 *
14 * An interface is a pure-virtual struct with a versioned `InterfaceName` ("bans.IBanService/2").
15 * Bump the version whenever the vtable or a parameter's meaning changes, so a stale consumer gets
16 * nullptr instead of a mismatched vtable. Each plugin has its own allocator: never transfer
17 * ownership through an interface, and let no exception escape one.
18 */
20{
21public:
22 /** @p services is the host's table; it outlives the exchange. */
24
25 /** Offer @p impl while the returned Subscription lives. Name @p T explicitly,
26 * `Publish<IBanService>(&_bans)`, so the stored pointer is the interface subobject the consumer
27 * casts back to. Keep the Subscription below @p impl, so the entry goes first. */
28 template <class T>
30 {
31 return PublishNamed(T::InterfaceName, static_cast<void*>(impl));
32 }
33
34 /** Offer @p impl as one of several @p T, told apart by @p key: `Publish<IMenuSection>(this, "admin")`. */
35 template <class T>
36 [[nodiscard]] Subscription Publish(T* impl, std::string_view key)
37 {
38 return PublishNamed(KeyedName(T::InterfaceName, key), static_cast<void*>(impl));
39 }
40
41 /** What any plugin published for @p T, or nullptr. Ask where you use it and do not keep it:
42 * the publisher can unload between callbacks, never inside one. */
43 template <class T>
44 T* Get() const
45 {
46 return static_cast<T*>(Find(T::InterfaceName));
47 }
48
49 /** What a plugin published for @p T under @p key, or nullptr. */
50 template <class T>
51 T* Get(std::string_view key) const
52 {
53 return static_cast<T*>(Find(KeyedName(T::InterfaceName, key)));
54 }
55
56private:
57 Subscription PublishNamed(std::string_view iface, void* impl);
58 void* Find(std::string_view iface) const;
59
60 static std::string KeyedName(std::string_view iface, std::string_view key)
61 {
62 return std::string(iface) + ":" + std::string(key);
63 }
64
65 IPluginServices& _services;
66};
67
68} // namespace VoltMod
Typed view of the host's table of interfaces plugins publish to each other.
ServiceExchange(IPluginServices &services)
Subscription Publish(T *impl, std::string_view key)
Subscription Publish(T *impl)
T * Get(std::string_view key) const
Owns one registration and releases it on destruction.
static std::string ReadFile(const std::filesystem::path &path)
Definition Loader.cpp:56