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