-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRegistry.hh
156 lines (133 loc) · 4.17 KB
/
Registry.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?hh // strict
/**
* @copyright 2010-2015, The Titon Project
* @license http://opensource.org/licenses/bsd-license.php
* @link http://titon.io
*/
namespace Titon\Utility;
use Titon\Utility\Exception\InvalidObjectException;
use Titon\Utility\Exception\MissingObjectException;
use \ReflectionClass;
/**
* The Registry acts a central hub where any part of the application can access a single instance of a stored object.
* It registers all objects into the class to store in memory and be re-usable later at any given time.
*
* @package Titon\Utility
*/
class Registry<T> {
/**
* Objects that have been registered into memory. The array index is represented by the namespace convention,
* where as the array value would be the matching instantiated object.
*
* @var \Titon\Utility\RegistryMap
*/
protected static RegistryMap<T> $registered = Map {};
/**
* Return all registered objects.
*
* @return \Titon\Utility\RegistryMap
*/
public static function all(): RegistryMap<T> {
return static::$registered;
}
/**
* Register a file into memory and return an instantiated object.
*
* @uses Titon\Utility\Path
*
* @param string $key
* @param \Titon\Utility\ArgumentList $args
* @param bool $store
* @return T
*/
public static function factory(string $key, ArgumentList $args, bool $store = true): T {
if (static::has($key)) {
return static::get($key);
}
$namespace = Path::toNamespace($key);
$object = (new ReflectionClass($namespace))->newInstanceArgs($args);
if ($store) {
$object = static::set($object, $key);
}
return $object;
}
/**
* Flush the registry by removing all stored objects.
*/
public static function flush(): void {
static::$registered->clear();
}
/**
* Return the object assigned to the given key.
*
* @param string $key
* @return T
* @throws \Titon\Utility\Exception\MissingObjectException
*/
public static function get(string $key): T {
if (static::has($key)) {
$object = static::$registered[$key];
if (is_callable($object)) {
// UNSAFE
// Because you can't `invariant()` a callable
$object = static::set(call_user_func($object), $key);
}
return $object;
}
throw new MissingObjectException(sprintf('Object %s does not exist in the registry', $key));
}
/**
* Checks to see if an object has been registered (instantiated).
*
* @param string $key
* @return bool
*/
public static function has(string $key): bool {
return static::$registered->contains($key);
}
/**
* Returns an array of all objects that have been registered; returns the keys and not the objects.
*
* @return Vector<string>
*/
public static function keys(): Vector<string> {
return static::$registered->keys();
}
/**
* Register a callback that will be lazily loaded when called.
*
* @param string $key
* @param \Titon\Utility\RegistryCallback $callback
*/
public static function register(string $key, RegistryCallback<T> $callback): void {
// UNSAFE
// Since the property generics is `T` while the callback is `RegistryCallback<T>`
static::$registered[$key] = $callback;
}
/**
* Remove an object from registry.
*
* @param string $key
*/
public static function remove(string $key): void {
static::$registered->remove($key);
}
/**
* Store an object into registry.
*
* @param T $object
* @param string $key
* @return T
* @throws \Titon\Utility\Exception\InvalidObjectException
*/
public static function set(T $object, string $key = ''): T {
if (!is_object($object)) {
throw new InvalidObjectException('The object to register must be instantiated');
}
if (!$key) {
$key = get_class($object);
}
static::$registered[$key] = $object;
return $object;
}
}