🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2.3 KiB

Crash Course: service locator

Table of Contents

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.
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.
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:

// 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):

// 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:

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...);
    // ...
}