Files
entt/docs/md/locator.md
Michele Caini 112d13c127 updated doc
2019-03-28 14:56:50 +01:00

76 lines
2.3 KiB
Markdown

# Crash Course: service locator
<!--
@cond TURN_OFF_DOXYGEN
-->
# Table of Contents
* [Introduction](#introduction)
* [Service locator](#service-locator)
<!--
@endcond TURN_OFF_DOXYGEN
-->
# Introduction
Usually service locators are tightly bound to the services they expose and it's
hard to define a general purpose solution. This template based implementation
tries to fill the gap and to get rid of the burden of defining a different
specific locator for each application.<br/>
This class is tiny, partially unsafe and thus risky to use. Moreover it doesn't
fit probably most of the scenarios in which a service locator is required. Look
at it as a small tool that can sometimes be useful if users know how to handle
it.
# Service locator
The API is straightforward. The basic idea is that services are implemented by
means of interfaces and rely on polymorphism.<br/>
The locator is instantiated with the base type of the service if any and a
concrete implementation is provided along with all the parameters required to
initialize it. As an example:
```cpp
// the service has no base type, a locator is used to treat it as a kind of singleton
entt::service_locator<my_service>::set(params...);
// sets up an opaque service
entt::service_locator<audio_interface>::set<audio_implementation>(params...);
// resets (destroys) the service
entt::service_locator<audio_interface>::reset();
```
The locator can also be queried to know if an active service is currently set
and to retrieve it if necessary (either as a pointer or as a reference):
```cpp
// no service currently set
auto empty = entt::service_locator<audio_interface>::empty();
// gets a (possibly empty) shared pointer to the service ...
std::shared_ptr<audio_interface> ptr = entt::service_locator<audio_interface>::get();
// ... or a reference, but it's undefined behaviour if the service isn't set yet
audio_interface &ref = entt::service_locator<audio_interface>::ref();
```
A common use is to wrap the different locators in a container class, creating
aliases for the various services:
```cpp
struct locator {
using camera = entt::service_locator<camera_interface>;
using audio = entt::service_locator<audio_interface>;
// ...
};
// ...
void init() {
locator::camera::set<camera_null>();
locator::audio::set<audio_implementation>(params...);
// ...
}
```