blob: 2e78bcaf17fb7df460618a160b2ca5efcb275756 [file] [log] [blame]
Zach Johnson429c94b2019-04-25 22:24:54 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <functional>
20#include <vector>
21#include <map>
22
23#include "os/log.h"
24
25namespace bluetooth {
26
27class Module;
28class ModuleRegistry;
29
30class ModuleFactory {
31 friend ModuleRegistry;
32 public:
33 ModuleFactory(std::function<Module*()> ctor);
34
35 private:
36 std::function<Module*()> ctor_;
37};
38
39class ModuleList {
40 friend ModuleRegistry;
41 public:
42 template <class T>
43 void add() {
44 list_.push_back(&T::Factory);
45 }
46
47 private:
48 std::vector<const ModuleFactory*> list_;
49};
50
51// Each leaf node module must have a factory like so:
52//
53// static const ModuleFactory Factory;
54//
55// which will provide a constructor for the module registry to call.
56// The module registry will also use the Factory as the identifier
57// for that module.
58class Module {
59 friend ModuleRegistry;
60 public:
61 virtual ~Module() = default;
62 protected:
63 // Populate the provided list with modules that must start before yours
64 virtual void ListDependencies(ModuleList* list) = 0;
65
66 // You can grab your started dependencies from the registry in this call
67 virtual void Start(const ModuleRegistry* registry) = 0;
68
69 // Release all resources, you're about to be deleted
70 virtual void Stop(const ModuleRegistry* registry) = 0;
71};
72
73class ModuleRegistry {
74 public:
75 template <class T>
76 T* GetInstance() const {
77 auto instance = started_modules_.find(&T::Factory);
78 ASSERT(instance != started_modules_.end());
79 return static_cast<T *>(instance->second);
80 };
81
82 template <class T>
83 bool IsStarted() const {
84 return IsStarted(&T::Factory);
85 }
86
87 bool IsStarted(const ModuleFactory* factory) const;
88
89 // Start all the modules on this list and their dependencies
90 // in dependency order
91 void Start(ModuleList* modules);
92
93 // Stop all running modules in reverse order of start
94 void StopAll();
95
96 private:
97 std::map<const ModuleFactory*, Module*> started_modules_;
98 std::vector<const ModuleFactory*> start_order_;
99};
100
101} // namespace bluetooth