Turi Create  4.0
globals.hpp
1 /* Copyright © 2017 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 #ifndef TURI_GLOBALS_GLOBALS_HPP
7 #define TURI_GLOBALS_GLOBALS_HPP
8 #include <string>
9 #include <vector>
10 #include <map>
11 #include <utility>
12 #include <functional>
13 namespace turi {
14 
15 class flexible_type;
16 
17 extern std::string GLOBALS_MAIN_PROCESS_PATH;
18 extern std::string GLOBALS_PYTHON_EXECUTABLE;
19 
20 namespace globals {
21 
22 template <typename T>
23 struct register_global;
24 /**
25  * \defgroup globals Global Parameter Registration
26  *
27  * \brief Global configuration manager that allows config to be set by environment variables.
28 */
29 
30 
31 
32 /**
33  * Registers an integral point global value.
34  *
35  * \ingroup globals
36  * Registers an integral point global value.
37  *
38  * This should not be used directly. Use \ref REGISTER_GLOBAL or
39  * \ref REGISTER_GLOBAL_WITH_CHECKS
40  *
41  * \param The name of the value.
42  * TURI_{name} will be the environment variable which modifies this value.
43  * By convention, this should be in all caps
44  * \param value A reference to the value.
45  * Value should be initialized the the default values.
46  * \param runtime_modifiable Whether this can be set only by environment
47  * variables or at runtime.
48  * \param value_check A callback function which checks the value of the value.
49  * This should be a simple lambda. (preferable +[](double) {...}) and should not
50  * capture anything. If the lambda returns true, the value changes are accepted.
51  * Defaults to nullptr in which case all value changes will be accepted.
52  */
53 template <>
54 struct register_global<int64_t>{
55  register_global(std::string name,
56  int64_t* value,
57  bool runtime_modifiable,
58  std::function<bool(int64_t)> value_check = nullptr);
59 };
60 
61 /**
62  * Registers a floating point global value.
63  *
64  * \ingroup globals
65  * Registers an integral point global value.
66  *
67  * This should not be used directly. Use \ref REGISTER_GLOBAL or
68  *
69  * \ref REGISTER_GLOBAL_WITH_CHECKS
70  * \param The name of the value.
71  * TURI_{name} will be the environment variable which modifies this value.
72  * By convention, this should be in all caps
73  * \param value A reference to the value.
74  * Value should be initialized the the default values.
75  * \param runtime_modifiable Whether this can be set only by environment
76  * variables or at runtime.
77  * \param value_check A callback function which checks the value of the value.
78  * This should be a simple lambda. (preferable +[](double) {...}) and should not
79  * capture anything. If the lambda returns true, the value changes are accepted.
80  * Defaults to nullptr in which case all value changes will be accepted.
81  */
82 template <>
83 struct register_global<double>{
84  register_global(std::string name,
85  double* value,
86  bool runtime_modifiable,
87  std::function<bool(double)> value_check = nullptr);
88 };
89 
90 
91 /**
92  * Registers a string global value.
93  *
94  * \ingroup globals
95  * Registers an integral point global value.
96  *
97  * This should not be used directly. Use \ref REGISTER_GLOBAL or
98  *
99  * \param The name of the value.
100  * TURI_{name} will be the environment variable which modifies this value.
101  * By convention, this should be in all caps
102  * \param value A reference to the value.
103  * Value should be initialized the the default values.
104  * \param runtime_modifiable Whether this can be set only by environment
105  * variables or at runtime.
106  * \param value_check A callback function which checks the value of the value.
107  * This should be a simple lambda. (preferable +[](double) {...}) and should not
108  * capture anything. If the lambda returns true, the value changes are accepted.
109  * Defaults to nullptr in which case all value changes will be accepted.
110  */
111 template <>
112 struct register_global<std::string>{
113  register_global(std::string name,
114  std::string* value,
115  bool runtime_modifiable,
116  std::function<bool(std::string)> value_check = nullptr);
117 };
118 
119 
120 
121 /**
122  * Lists all the global values. If runtime_modifiable == true, lists all
123  * global values which can be modified at runtime. If runtime == false, lists
124  * all global values which can only be modified by environment variables.
125  */
126 std::vector<std::pair<std::string, flexible_type> > list_globals(bool runtime_modifiable);
127 
128 /**
129  * \ingroup globals
130  * Gets a value of a single global value. There are a few builtins.
131  * UNITY_SERVER_BINARY: The location of the unity_server executable (for instance ./unity_server)
132  * UNITY_SERVER_PATH: The path of the unity_server executable (for instance
133  *
134  */
135 flexible_type get_global(std::string name);
136 
137 /**
138  * \ingroup globals
139  * Global assignment error codes
140  */
142  SUCCESS = 0,
143  NO_NAME = 1,
144  NOT_RUNTIME_MODIFIABLE = 2,
145  INVALID_VAL = 3
146 };
147 
148 /**
149  * \ingroup globals
150  * Sets a modifiable global value. Return set_global_error_codes::SUCCESS (0)
151  * on success and otherwise on failure.
152  */
153 set_global_error_codes set_global(std::string name, flexible_type val);
154 
155 /**
156  * \ingroup globals
157  * Initialize all registered global variables from environment variables.
158  * Also initializes the globals
159  * GLOBALS_MAIN_PROCESS_PATH from root_path which is the root directory of installation
160  */
161 void initialize_globals_from_environment(std::string root_path);
162 
163 } // namespace globals
164 } // namespace turi
165 
166 /**
167  * \ingroup globals
168  * Register a global variable.
169  *
170  * \param type The type of the variable. Must be integral, string, or double.
171  * \param varname The variable name. This variable can then be modified by
172  * setting the environment variable with the same name as the variable (
173  * prefixxed with TURI_)
174  * \param runtime_modifiable If false, this variable can only be modified by
175  * setting an environment variable. If true, it can be changed at runtime to
176  * any value.
177  *
178  * Example:
179  * REGISTER_GLOBAL(size_t, GLOBAL_PIKA_PIKA, false)
180  *
181  * Then setting the environment variable TURI_GLOBAL_PIKA_PIKA will
182  * change the value of the variable.
183  *
184  * REGISTER_GLOBAL(size_t, GLOBAL_PIKA_PIKA, true)
185  *
186  * Will allow the variable to be modified at runtime via Python.
187  */
188 #define REGISTER_GLOBAL(type, varname, runtime_modifiable) \
189  static auto __ ## varname ## __register__ ## instance = \
190  ::turi::globals::register_global \
191  <type>("TURI_" #varname, \
192  (type*)(&varname), \
193  runtime_modifiable);
194 
195 
196 /**
197  * \ingroup globals
198  * Register a global variable with value checking.
199  *
200  * \param type The type of the variable. Must be integral, string, or double.
201  * \param varname The variable name. This variable can then be modified by
202  * setting the environment variable with the same name as the variable (
203  * prefixxed with TURI_)
204  * \param runtime_modifiable If false, this variable can only be modified by
205  * setting an environment variable. If true, it can be changed at runtime to
206  * any value.
207  * \param lambda A function pointer / lambda function which checks the value
208  * when a value change is requested. The function should take a single input
209  * of the new value, and return a boolean value. (true for good, and false for
210  * bad). This lambda should be self contained and should not be dependent on
211  * other global objects since this will cause order of construction/destruction
212  * issues.
213  *
214  * Example:
215  * REGISTER_GLOBAL_WITH_CHECKS(size_t, GLOBAL_PIKA_PIKA, false.
216  * +[](size_t i){ return i >= 1024})
217  *
218  * Then setting the environment variable TURI_GLOBAL_PIKA_PIKA will
219  * change the value of the variable but it will only succeed if the value
220  * is greater than 1024.
221  *
222  * REGISTER_GLOBAL(size_t, GLOBAL_PIKA_PIKA, true)
223  *
224  * Will allow the variable to be modified at runtime via Python
225  * But the change will only succeed if the value is greater than 1024.
226  */
227 #define REGISTER_GLOBAL_WITH_CHECKS(type, varname, runtime_modifiable, lambda) \
228  static auto __ ## varname ## __register__ ## instance = \
229  ::turi::globals::register_global \
230  <type>("TURI_" #varname, \
231  (type*)(&varname), \
232  runtime_modifiable, \
233  lambda);
234 
235 #endif
set_global_error_codes set_global(std::string name, flexible_type val)
void initialize_globals_from_environment(std::string root_path)
STL namespace.
flexible_type get_global(std::string name)