TorchCraftAI
A bot for machine learning research on StarCraft: Brood War
registry.h
1 /*
2  * Copyright (c) 2017-present, Facebook, Inc.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #pragma once
9 
10 #include "common/str.h"
11 
12 #include <functional>
13 #include <list>
14 #include <memory>
15 #include <typeindex>
16 #include <unordered_map>
17 #include <vector>
18 
19 namespace cherrypi {
20 
21 #define REGISTER_SUBCLASS_0(Base, Derived) \
22  namespace { \
23  bool _registered_##Base##_##Derived ATTR_UNUSED = \
24  SubclassRegistry<Base>::registerSubclass( \
25  typeid(Derived), \
26  #Derived, \
27  []() -> std::shared_ptr<Base> { \
28  return std::make_shared<Derived>(); \
29  }); \
30  }
31 
32 #define REGISTER_SUBCLASS_1(Base, Derived, Arg1) \
33  namespace { \
34  bool _registered_##Base##_##Derived ATTR_UNUSED = \
35  SubclassRegistry<Base, Arg1>::registerSubclass( \
36  typeid(Derived), \
37  #Derived, \
38  [](Arg1 arg1) -> std::shared_ptr<Base> { \
39  return std::make_shared<Derived>(arg1); \
40  }); \
41  }
42 
43 #define REGISTER_SUBCLASS_3(Base, Derived, Arg1, Arg2, Arg3) \
44  namespace { \
45  bool _registered_##Base##_##Derived ATTR_UNUSED = \
46  SubclassRegistry<Base, Arg1, Arg2, Arg3>::registerSubclass( \
47  typeid(Derived), \
48  #Derived, \
49  [](Arg1 arg1, Arg2 arg2, Arg3 arg3) -> std::shared_ptr<Base> { \
50  return std::make_shared<Derived>(arg1, arg2, arg3); \
51  }); \
52  }
53 
54 template <typename Base, typename... Args>
56  public:
57  using Ctor = std::function<std::shared_ptr<Base>(Args...)>;
58  struct SubclassInfo {
59  std::type_index type;
60  std::string name;
62 
64  std::type_index const& type,
65  std::string const& name,
66  Ctor ctor)
67  : type(type), name(name), ctor(std::move(ctor)) {}
68  };
69 
70  static bool registerSubclass(
71  std::type_index const& type,
72  std::string const& name,
73  Ctor ctor) {
74  auto& reg = registry();
75  if (reg.byType.find(type) == reg.byType.end()) {
76  reg.info.emplace_back(type, name, std::move(ctor));
77  reg.byType.emplace(type, reg.info.back());
78  reg.byName.emplace(common::stringToLower(name), reg.info.back());
79  }
80  return true;
81  }
82 
83  static SubclassInfo* record(std::string const& name) {
84  auto& reg = registry();
85  auto lowerName = common::stringToLower(name);
86  auto it = reg.byName.find(lowerName);
87  if (it == reg.byName.end()) {
88  return nullptr;
89  }
90  return &it->second;
91  }
92 
93  static std::vector<SubclassInfo*> subclasses() {
94  std::vector<SubclassInfo*> result;
95  for (auto& it : registry().info) {
96  result.push_back(&it);
97  }
98  return result;
99  }
100 
101  template <typename... CArgs>
102  static std::shared_ptr<Base> create(
103  std::string const& name,
104  CArgs&&... args) {
105  auto& reg = registry();
106  auto lowerName = common::stringToLower(name);
107  auto it = reg.byName.find(lowerName);
108  if (it == reg.byName.end()) {
109  return nullptr;
110  }
111  return it->second.ctor(std::forward<CArgs>(args)...);
112  }
113 
114  static std::string name(std::type_index const& type) {
115  auto& reg = registry();
116  auto it = reg.byType.find(type);
117  if (it == reg.byType.end()) {
118  return std::string();
119  }
120  return it->second.name;
121  }
122 
123  template <typename Derived>
124  static std::string name() {
125  return name(typeid(Derived));
126  }
127 
128  private:
129  struct Registry {
130  std::list<SubclassInfo> info;
131  std::unordered_map<std::type_index, SubclassInfo&> byType;
132  // Keys are lower-case
133  std::unordered_map<std::string, SubclassInfo&> byName;
134  };
135 
136  static Registry& registry() {
137  static Registry reg_;
138  return reg_;
139  }
140 
141  SubclassRegistry() = delete;
142 };
143 
144 } // namespace cherrypi
std::string stringToLower(T &&str)
Definition: str.h:53
SubclassInfo(std::type_index const &type, std::string const &name, Ctor ctor)
Definition: registry.h:63
STL namespace.
static std::string name(std::type_index const &type)
Definition: registry.h:114
Ctor ctor
Definition: registry.h:61
std::string name
Definition: registry.h:60
static std::vector< SubclassInfo * > subclasses()
Definition: registry.h:93
Definition: registry.h:55
Main namespace for bot-related code.
Definition: areainfo.cpp:17
static std::string name()
Definition: registry.h:124
static std::shared_ptr< Base > create(std::string const &name, CArgs &&...args)
Definition: registry.h:102
std::function< std::shared_ptr< Base >(Args...)> Ctor
Definition: registry.h:57
static bool registerSubclass(std::type_index const &type, std::string const &name, Ctor ctor)
Definition: registry.h:70
static SubclassInfo * record(std::string const &name)
Definition: registry.h:83
std::type_index type
Definition: registry.h:59