aboutsummaryrefslogtreecommitdiff
path: root/kapi/kapi/devices/device_registry.hpp
blob: 346b9a10b7ff81ac58a3d4feb09e6f70113b4f32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#ifndef TEACHOS_KAPI_DEVICES_DEVICE_REGISTRY_HPP
#define TEACHOS_KAPI_DEVICES_DEVICE_REGISTRY_HPP

// IWYU pragma: private, include <kapi/devices.hpp>

#include <kapi/devices/device.hpp>
#include <kapi/tracked_mutex.hpp>

#include <kstd/flat_map.hpp>
#include <kstd/memory.hpp>
#include <kstd/string.hpp>
#include <kstd/vector.hpp>

#include <string_view>

namespace kapi::devices
{

  //! @addtogroup kapi-devices-kernel-defined
  //! @{

  //! The interface for types interested in being notified about changes in the device registry.
  struct device_registry_observer
  {
    //! Enable correct destruction through base pointers.
    virtual ~device_registry_observer() = default;

    //! Called after a device has been added to the registry.
    //!
    //! @param device The device that was added.
    virtual auto on_device_added(kstd::shared_ptr<device> const & device) -> void = 0;

    //! Called after a device has been removed from the registry.
    //!
    //! @param device The device that was remove.
    virtual auto on_device_removed(device & device) -> void = 0;
  };

  //! @}

  //! @addtogroup kapi-devices-kernel-defined
  //! @{

  struct device_registry
  {
    device_registry() = default;

    //! Initialize the global singleton registry instance.
    auto static init() -> void;

    //! Get the global singleton registry instance.
    auto static get() -> device_registry &;

    //! Add a new device to the kernel's device registry.
    //!
    //! @param device The device to register.
    //! @return true if the device was registered successfully, false otherwise.
    auto add(kstd::shared_ptr<device> const & device) -> bool;

    //! Remove a device from the kernel's device registry.
    //!
    //! @param device The device to unregister.
    //! @return true if the device was unregistered successfully, false otherwise.
    auto remove(device & device) -> bool;

    //! Find a device by its name.
    //!
    //! @param name the name of the device.
    //! @return a shared pointer to the device iff. the device was found and is still alive, nullptr otherwise.
    [[nodiscard]] auto find(std::string_view name) const -> kstd::shared_ptr<device>;

    //! Get all currently registered devices.
    //!
    //! @return every device current reachable through the registry.
    [[nodiscard]] auto all() const -> kstd::vector<kstd::shared_ptr<device>>;

    //! Subscribe to device registry notifications.
    //!
    //! @param observer The observer to notify.
    auto subscribe(kstd::weak_ptr<device_registry_observer> observer) -> void;

  private:
    mutable tracked_mutex m_lock{};

    kstd::flat_map<kstd::string, kstd::weak_ptr<device>> m_devices{};
    kstd::vector<kstd::weak_ptr<device_registry_observer>> m_observers{};
  };

  //! @}

}  // namespace kapi::devices

#endif