-
Notifications
You must be signed in to change notification settings - Fork 27
RSDK-9298: Instance class #374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
31437c3
932ebaa
04d0158
a105cef
403f316
27eeb13
ce2aa8c
e5cf6d0
85194da
5024d3a
ef8ec8e
16113fd
216e5e2
4771390
18d26c9
6018323
5535616
eeac195
7560f6d
4e25d35
55baa6c
10cd711
c745422
75ab450
fc21c35
1758ee9
cd1d8c5
6e154ce
f02ce0f
e80bf80
185121a
7a747ec
9c4dc97
30fe47e
7409dc7
c4aaadf
d2ae2d7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| #include <viam/sdk/common/instance.hpp> | ||
|
|
||
| #include <atomic> | ||
|
|
||
| #include <viam/sdk/common/exception.hpp> | ||
| #include <viam/sdk/common/private/instance.hpp> | ||
| #include <viam/sdk/registry/registry.hpp> | ||
|
|
||
| namespace viam { | ||
| namespace sdk { | ||
|
|
||
| namespace { | ||
|
|
||
| // Memory region sentinel to check if object is being destroyed. | ||
| std::aligned_storage_t<sizeof(Instance), alignof(Instance)> sentinel; | ||
|
|
||
| std::atomic<Instance*> current_instance{nullptr}; | ||
|
|
||
| } // namespace | ||
|
|
||
| Instance::Instance() { | ||
| Instance* expected = nullptr; | ||
|
|
||
| if (!current_instance.compare_exchange_strong(expected, this)) { | ||
| throw Exception("tried to create duplicate instance"); | ||
| } | ||
|
|
||
| impl_ = std::make_unique<Instance::Impl>(); | ||
| impl_->registry.initialize(); | ||
| } | ||
|
|
||
| Instance::~Instance() { | ||
| current_instance.store(reinterpret_cast<Instance*>(&sentinel)); | ||
| impl_.reset(); | ||
| } | ||
|
|
||
| Instance& Instance::current(Instance::Creation creation) { | ||
| if (!current_instance.load()) { | ||
| if (creation == Creation::if_needed) { | ||
| // This variable declaration calls the default ctor, storing a current instance. | ||
| static Instance inst; // NOLINT (misc-const-correctness) | ||
| } else { | ||
| throw Exception("Instance has not yet been created"); | ||
| } | ||
| } | ||
|
|
||
| Instance* current = current_instance.load(); | ||
|
|
||
| if (current == reinterpret_cast<Instance*>(&sentinel)) { | ||
| throw Exception("instance was destroyed"); | ||
| } | ||
|
Comment on lines
+49
to
+51
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (q) pardon my ignorance, I don't think I fully understand this. Under what conditions will this exception throw?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh wait actually this gets to your comment above about making it an error to have multiple instances even if non-overlapping, so it already is an error to have multiple of them |
||
|
|
||
| return *current; | ||
| } | ||
|
|
||
| } // namespace sdk | ||
| } // namespace viam | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| #pragma once | ||
|
|
||
| #include <memory> | ||
|
|
||
| namespace viam { | ||
| namespace sdk { | ||
|
|
||
| /// @brief Instance management for Viam C++ SDK applications. | ||
| /// This is a single instance class which is responsible for global setup and teardown related to | ||
| /// the SDK. An Instance must be constructed before doing anything else in a program, and it must | ||
| /// remain alive in a valid state for the duration of the program. Creating multiple Instance | ||
| /// objects in the same program is an error. | ||
| class Instance { | ||
| public: | ||
| /// @brief Enumeration for creation behavior of @ref current | ||
| enum class Creation { | ||
| open_existing, ///< Instance must already exist | ||
| if_needed ///< Use existing instance if present, else create one. | ||
| }; | ||
|
|
||
| Instance(); | ||
| ~Instance(); | ||
|
|
||
| /// @brief Get the current Instance according to the Creation behavior. | ||
| /// @throws an @ref Exception if current(Creation::open_existing) is called when an instance has | ||
| /// not yet been constructed. | ||
| static Instance& current(Creation); | ||
|
|
||
| private: | ||
| friend class Registry; | ||
|
|
||
| struct Impl; | ||
| std::unique_ptr<Impl> impl_; | ||
| }; | ||
|
|
||
| } // namespace sdk | ||
| } // namespace viam |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| #pragma once | ||
|
|
||
| #include <viam/sdk/common/instance.hpp> | ||
| #include <viam/sdk/registry/registry.hpp> | ||
|
|
||
| namespace viam { | ||
| namespace sdk { | ||
|
|
||
| struct Instance::Impl { | ||
| Registry registry; | ||
| }; | ||
|
|
||
| } // namespace sdk | ||
| } // namespace viam |
Uh oh!
There was an error while loading. Please reload this page.