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