1import logging; logger = logging.getLogger("morse." + __name__) 2import datetime 3from ctypes import * 4from morse.middleware import AbstractDatastream 5from morse.core.datastream import * 6 7try: 8 P = CDLL("libposterLib.so") 9except OSError: 10 import morse.core.blenderapi 11 if not morse.core.blenderapi.fake: 12 logger.error('Cannot find libposterLib.so : check your LD_LIBRARY_PATH') 13 raise 14 15 16class PosterNotFound(Exception): 17 def __init__(self, value): 18 self.value = value 19 def __str__(self): 20 return repr(self.value) 21 22class InvalidRead(Exception): 23 def __init__(self, value): 24 self.value = value 25 def __str__(self): 26 return repr(self.value) 27 28def poster_name(component_name, mw_data): 29 # Check if the name of the poster has been given in mw_data 30 poster_name = '' 31 if 'poster' in mw_data: 32 poster_name = mw_data['poster'] 33 else: 34 # Compose the name of the poster, based on the parent and module names 35 poster_name = component_name 36 37 return poster_name 38 39class DummyPoster: 40 def __init__(self, name): 41 self.poster_id = c_void_p() 42 c_name = create_string_buffer(bytes(name, 'utf-8')) 43 P.posterCreate(c_name, 8, byref(self.poster_id)) 44 45 def __del__(self): 46 P.posterDelete(self.poster_id) 47 self.poster_id = None 48 49class PocolibsDataStreamOutput(AbstractDatastream): 50 51 def initialize(self, kind): 52 self.poster_id = c_void_p() 53 o = kind() 54 self.name = poster_name(self.component_name, self.kwargs) 55 c_name = create_string_buffer(bytes(self.name, 'utf-8')) 56 logger.info("Create poster %s of size %d" % (self.name, sizeof(o))) 57 r = P.posterCreate(c_name, sizeof(o), byref(self.poster_id)) 58 if r != 0: 59 P.posterFind(c_name, byref(self.poster_id)) 60 61 def write(self, obj): 62 r = P.posterWrite(self.poster_id, 0, byref(obj), sizeof(obj)) 63 if r != sizeof(obj): 64 raise "too bad : write failed" 65 66 def finalize(self): 67 logger.info("Releaase poster %s" % self.name) 68 P.posterDelete(self.poster_id) 69 self.poster_id = None 70 71class PocolibsDataStreamInput(AbstractDatastream): 72 def initialize(self, kind): 73 self.poster_id = c_void_p() 74 name = poster_name(self.component_name, self.kwargs) 75 delay = self.kwargs.get('delay', True) 76 self.name = name 77 self.c_name = create_string_buffer(bytes(name, 'utf-8')) 78 79 self.o = kind() 80 self.found = False 81 self._find() 82 if not self.found and not delay: 83 raise PosterNotFound(self.name) 84 85 def _find(self): 86 logger.debug("Searching to read %s" % self.name) 87 r = P.posterFind(self.c_name, byref(self.poster_id)) 88 if r == 0: 89 self.found = True 90 91 def read(self): 92 if not self.found: 93 self._find() 94 95 if self.found: 96 r = P.posterRead(self.poster_id, 0, byref(self.o), sizeof(self.o)) 97 if r != sizeof(self.o): 98 raise InvalidRead(self.name) 99 return self.o 100 else: 101 return None 102 103 def finalize(self): 104 if self.found: 105 P.posterForget(self.poster_id) 106 107class PocolibsDatastreamManager(DatastreamManager): 108 """ Handle communication between Blender and Pocolibs.""" 109 110 def compute_date(): 111 """ Compute the current time 112 113 ( we only require that the date 114 increases using a constant step so real time is ok) 115 """ 116 t = datetime.datetime.now() 117 date = int(t.hour * 3600* 1000 + t.minute * 60 * 1000 + 118 t.second * 1000 + t.microsecond / 1000) 119 120 return date, t 121