blob: fc3292d5da80ae2e3d3d6db5d47d74871b091308 [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"
Zach Johnson7ea20682019-04-29 14:48:42 -070024#include "os/handler.h"
25#include "os/thread.h"
Zach Johnson429c94b2019-04-25 22:24:54 -070026
27namespace bluetooth {
28
29class Module;
30class ModuleRegistry;
31
32class ModuleFactory {
33 friend ModuleRegistry;
34 public:
35 ModuleFactory(std::function<Module*()> ctor);
36
37 private:
38 std::function<Module*()> ctor_;
39};
40
41class ModuleList {
42 friend ModuleRegistry;
43 public:
44 template <class T>
45 void add() {
46 list_.push_back(&T::Factory);
47 }
48
49 private:
50 std::vector<const ModuleFactory*> list_;
51};
52
53// Each leaf node module must have a factory like so:
54//
55// static const ModuleFactory Factory;
56//
57// which will provide a constructor for the module registry to call.
Zach Johnson7ea20682019-04-29 14:48:42 -070058// The module registry will also use the factory as the identifier
Zach Johnson429c94b2019-04-25 22:24:54 -070059// for that module.
60class Module {
61 friend ModuleRegistry;
62 public:
63 virtual ~Module() = default;
64 protected:
65 // Populate the provided list with modules that must start before yours
66 virtual void ListDependencies(ModuleList* list) = 0;
67
68 // You can grab your started dependencies from the registry in this call
69 virtual void Start(const ModuleRegistry* registry) = 0;
70
71 // Release all resources, you're about to be deleted
72 virtual void Stop(const ModuleRegistry* registry) = 0;
Zach Johnson7ea20682019-04-29 14:48:42 -070073
74 ::bluetooth::os::Handler* GetHandler();
75
76 private:
77 ::bluetooth::os::Handler* handler_;
Zach Johnson429c94b2019-04-25 22:24:54 -070078};
79
80class ModuleRegistry {
81 public:
82 template <class T>
83 T* GetInstance() const {
84 auto instance = started_modules_.find(&T::Factory);
85 ASSERT(instance != started_modules_.end());
86 return static_cast<T *>(instance->second);
87 };
88
89 template <class T>
90 bool IsStarted() const {
91 return IsStarted(&T::Factory);
92 }
93
94 bool IsStarted(const ModuleFactory* factory) const;
95
96 // Start all the modules on this list and their dependencies
97 // in dependency order
Zach Johnson7ea20682019-04-29 14:48:42 -070098 void Start(ModuleList* modules, ::bluetooth::os::Thread* thread);
Zach Johnson429c94b2019-04-25 22:24:54 -070099
Zach Johnsone0e158c2019-04-26 11:57:05 -0700100 template <class T>
Zach Johnson7ea20682019-04-29 14:48:42 -0700101 void Start(::bluetooth::os::Thread* thread) {
102 Start(&T::Factory, thread);
Zach Johnsone0e158c2019-04-26 11:57:05 -0700103 }
104
Zach Johnson7ea20682019-04-29 14:48:42 -0700105 void Start(const ModuleFactory* id, ::bluetooth::os::Thread* thread);
Zach Johnsone0e158c2019-04-26 11:57:05 -0700106
Zach Johnson429c94b2019-04-25 22:24:54 -0700107 // Stop all running modules in reverse order of start
108 void StopAll();
109
110 private:
111 std::map<const ModuleFactory*, Module*> started_modules_;
112 std::vector<const ModuleFactory*> start_order_;
113};
114
115} // namespace bluetooth