The Gaudi Framework  master (181af51f)
Loading...
Searching...
No Matches
cpluginsvc.py
Go to the documentation of this file.
11
12# cpluginsvc is a ctypes-based wrapper for the C-exposed API of GaudiPluginService
13__doc__ = """
14cpluginsvc is a ctypes-based wrapper for the C-API of the GaudiPluginService.
15
16e.g.:
17
18>>> from GaudiPluginService import cpluginsvc
19>>> for _,f in cpluginsvc.factories().items():
20... try:
21... f.load()
22... except Exception:
23... print ("** could not load [%s] for factory [%s]" % (f.library, f.name))
24... continue
25... print(f)
26... for k,v in f.properties.iteritems():
27... print ("\t%s: %s" % (k,v))
28"""
29
30import ctypes
31import ctypes.util
32
33__all__ = (
34 "Registry",
35 "registry",
36 "factories",
37 "Factory",
38 "Property",
39)
40
41_libname = None
42
43
45 if _libname:
46 return _libname
47 import platform
48
49 name = platform.system()
50
51 fname = {
52 "Darwin": "libGaudiPluginService.dylib",
53 "Windows": "libGaudiPluginService.dll",
54 "Linux": "libGaudiPluginService.so",
55 }[name]
56 return fname
57
58
59_libname = _get_filename()
60_lib = ctypes.CDLL(_libname, ctypes.RTLD_GLOBAL)
61
62
63class Registry(ctypes.Structure):
64 """Registry holds the list of factories known by the gaudi PluginService."""
65
66 _fields_ = [("_registry", ctypes.c_void_p)]
67
68 @property
69 def factories(self):
70 facts = {}
71 n = _lib.cgaudi_pluginsvc_get_factory_size(self)
72 for i in range(n):
73 f = _lib.cgaudi_pluginsvc_get_factory_at(self, i)
74 facts[f.name] = f
75 return facts
76
77 pass
78
79
80_instance = None
81
82
84 """registry returns the singleton-like instance of the plugin service."""
85
86 global _instance
87 if _instance:
88 return _instance
89 _instance = _lib.cgaudi_pluginsvc_instance()
90 return _instance
91
92
94 """
95 factories returns the list of components factory informations known to the plugin service
96 """
97 return registry().factories
98
99
100class Factory(ctypes.Structure):
101 """
102 Factory holds informations about a component's factory:
103 - its name
104 - the library hosting that component
105 - the type of component (algorithm, service, tool, ...)
106 - the return type of this factory
107 - the C++ class name of that component
108 - the properties which may decorate that component.
109 """
110
111 _fields_ = [
112 ("_registry", Registry),
113 ("_id", ctypes.c_char_p),
114 ]
115
116 @property
117 def name(self):
118 return self._id.decode("ascii")
119
120 @property
121 def library(self):
122 return _lib.cgaudi_factory_get_library(self).decode("ascii")
123
124 @property
125 def type(self):
126 return _lib.cgaudi_factory_get_type(self).decode("ascii")
127
128 @property
129 def classname(self):
130 return _lib.cgaudi_factory_get_classname(self).decode("ascii")
131
132 @property
133 def properties(self):
134 props = {}
135 nprops = _lib.cgaudi_factory_get_property_size(self)
136 for i in range(nprops):
137 prop = _lib.cgaudi_factory_get_property_at(self, i)
138 props[prop.key] = prop.value
139 return props
140
141 def load(self):
142 """load the C++ library hosting this factory"""
143 return ctypes.CDLL(self.library, ctypes.RTLD_GLOBAL)
144
145 def __repr__(self):
146 return "<Factory id=%s library=%s type=%s class=%s props=%d>" % (
147 self.name,
148 self.library,
149 self.type,
151 len(self.properties),
152 )
153
154 pass
155
156
157class Property(ctypes.Structure):
158 """
159 Property is a pair (key, value) optionally decorating a factory.
160 It is used to attach additional informations about a factory.
161 """
162
163 _fields_ = [
164 ("_registry", Registry),
165 ("_id", ctypes.c_char_p),
166 ("_key", ctypes.c_char_p),
167 ]
168
169 @property
170 def key(self):
171 return _lib.cgaudi_property_get_key(self).decode("ascii")
172
173 @property
174 def value(self):
175 return _lib.cgaudi_property_get_value(self).decode("ascii")
176
177 pass
178
179
180_functions_list = [
181 (
182 "cgaudi_pluginsvc_instance",
183 [],
184 Registry,
185 ),
186 (
187 "cgaudi_pluginsvc_get_factory_size",
188 [Registry],
189 ctypes.c_int,
190 ),
191 (
192 "cgaudi_pluginsvc_get_factory_at",
193 [Registry, ctypes.c_int],
194 Factory,
195 ),
196 (
197 "cgaudi_factory_get_library",
198 [Factory],
199 ctypes.c_char_p,
200 ),
201 (
202 "cgaudi_factory_get_type",
203 [Factory],
204 ctypes.c_char_p,
205 ),
206 (
207 "cgaudi_factory_get_classname",
208 [Factory],
209 ctypes.c_char_p,
210 ),
211 (
212 "cgaudi_factory_get_property_size",
213 [Factory],
214 ctypes.c_int,
215 ),
216 (
217 "cgaudi_factory_get_property_at",
218 [Factory, ctypes.c_int],
219 Property,
220 ),
221 (
222 "cgaudi_property_get_key",
223 [Property],
224 ctypes.c_char_p,
225 ),
226 (
227 "cgaudi_property_get_value",
228 [Property],
229 ctypes.c_char_p,
230 ),
231]
232
233for f in _functions_list:
234 n = f[0]
235 func = getattr(_lib, n)
236 func.argtypes = f[1]
237 func.restype = f[2]
238 if len(f) == 4:
239 func.errcheck = f[3]
240 pass
241
242if __name__ == "__main__":
243 print("instance: %s" % registry())
244 print("factories: %d" % len(factories()))
245 for _, f in factories().items():
246 try:
247 f.load()
248 except Exception:
249 print("** could not load [%s] for factory [%s]" % (f.library, f.name))
250 continue
251 print(f)
252 for k, v in f.properties.items():
253 print("\t%s: %s" % (k, v))
254
255# EOF