The Gaudi Framework  v29r0 (ff2e7097)
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.LoadLibrary(_libname)
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 rtype(self):
116  return _lib.cgaudi_factory_get_rtype(self)
117 
118  @property
119  def classname(self):
120  return _lib.cgaudi_factory_get_classname(self)
121 
122  @property
123  def properties(self):
124  props = {}
125  nprops = _lib.cgaudi_factory_get_property_size(self)
126  for i in range(nprops):
127  prop = _lib.cgaudi_factory_get_property_at(self, i)
128  props[prop.key] = prop.value
129  return props
130 
131  def load(self):
132  '''load the C++ library hosting this factory
133  '''
134  return ctypes.cdll.LoadLibrary(self.library)
135 
136  def __repr__(self):
137  return "<Factory id=%s library=%s type=%s rtype=%s class=%s props=%d>" % (
138  self._id,
139  self.library,
140  self.type,
141  self.rtype,
142  self.classname,
143  len(self.properties),
144  )
145  pass
146 
147 
148 class Property(ctypes.Structure):
149  '''
150  Property is a pair (key, value) optionally decorating a factory.
151  It is used to attach additional informations about a factory.
152  '''
153  _fields_ = [
154  ("_registry", Registry),
155  ("_id", ctypes.c_char_p),
156  ("_key", ctypes.c_char_p),
157  ]
158 
159  @property
160  def key(self):
161  return _lib.cgaudi_property_get_key(self)
162 
163  @property
164  def value(self):
165  return _lib.cgaudi_property_get_value(self)
166 
167  pass
168 
169 
170 _functions_list = [
171  ("cgaudi_pluginsvc_instance",
172  [],
173  Registry,
174  ),
175 
176  ("cgaudi_pluginsvc_get_factory_size",
177  [Registry],
178  ctypes.c_int,
179  ),
180 
181  ("cgaudi_pluginsvc_get_factory_at",
182  [Registry, ctypes.c_int],
183  Factory,
184  ),
185 
186  ("cgaudi_factory_get_library",
187  [Factory],
188  ctypes.c_char_p,
189  ),
190 
191  ("cgaudi_factory_get_type",
192  [Factory],
193  ctypes.c_char_p,
194  ),
195 
196  ("cgaudi_factory_get_rtype",
197  [Factory],
198  ctypes.c_char_p,
199  ),
200 
201  ("cgaudi_factory_get_classname",
202  [Factory],
203  ctypes.c_char_p,
204  ),
205 
206  ("cgaudi_factory_get_property_size",
207  [Factory],
208  ctypes.c_int,
209  ),
210 
211  ("cgaudi_factory_get_property_at",
212  [Factory, ctypes.c_int],
213  Property,
214  ),
215 
216  ("cgaudi_property_get_key",
217  [Property],
218  ctypes.c_char_p,
219  ),
220 
221  ("cgaudi_property_get_value",
222  [Property],
223  ctypes.c_char_p,
224  )
225 ]
226 
227 for f in _functions_list:
228  n = f[0]
229  func = getattr(_lib, n)
230  func.argtypes = f[1]
231  func.restype = f[2]
232  if len(f) == 4:
233  func.errcheck = f[3]
234  pass
235 
236 
237 if __name__ == "__main__":
238  print ("instance: %s" % registry())
239  print ("factories: %d" % len(factories()))
240  for _, f in factories().items():
241  try:
242  f.load()
243  except Exception:
244  print (
245  "** could not load [%s] for factory [%s]" % (f.library, f.name))
246  continue
247  print f
248  for k, v in f.properties.items():
249  print ("\t%s: %s" % (k, v))
250 
251 # EOF
decltype(auto) range(Args &&...args)
Zips multiple containers together to form a single range.