class Drawing(Fap): PLAYABLE = True ACTIVATED = True def __init__(self, username, userid): self.rate = Rate(10) Fap.__init__(self, username, userid) print_flush("Init of DRAWING", self.model.height, self.model.width) def handle_message(self, json_data, path=None): # noqa print_flush("Received something :3") if json_data is None: raise ValueError("Error : message received on websocket is empty.") elif isinstance(json_data, str): data = loads(json_data) else: raise ValueError("Incorrect payload value type for Drawing Fapp") pixel = data['pixel'] color = data['color'] px_x = int(pixel['x']) px_y = int(pixel['y']) assert (isinstance(color['red'], int) and 0 <= color['red'] <= 255) assert (isinstance(color['green'], int) and 0 <= color['green'] <= 255) assert (isinstance(color['blue'], int) and 0 <= color['blue'] <= 255) self.model.set_pixel( px_x, px_y, rgb255_to_rgb(color['red'], color['green'], color['blue'])) def set_default_drawing(self): # Set the current model as the default drawing in database session = session_factory() try: fap = session.query(FappModel).filter_by(name='Drawing').first() if not fap: return False fap.default_params = dumps({"model": self.model.json()}) session.commit() finally: session.close() def run(self, params, expires_at=None): if 'model' in params and params['model'] != "": # Replay saved drawing self.model.set_from_json(params['model']) while True: self.send_model() self.rate.sleep() else: # Regular real-time drawing self.start_socket() while True: if SchedulerState.get_default_drawing_request(): self.set_default_drawing() self.send_model() self.rate.sleep()
def run(self, params, expires_at=None): self.start_socket() if not params: params = {} self.params = params self.rate_increase = params.get('speed', self.PARAMS_LIST.get('speed')) self.start_food = params.get('food', self.PARAMS_LIST.get('food')) rate = Rate(self.rate) self.model.set_all(self.BG_COLOR) self.model.set_pixel(self.HEAD[0], self.HEAD[1], self.PIXEL_COLOR) self.spawn_food(self.start_food) for x, y in self.FOOD_POSITIONS: self.model.set_pixel(x, y, self.FOOD_COLOR) self.send_model() print_flush("Started party with", self.start_food, "food.") while True: rate.sleep_dur = 1.0 / self.rate print_flush("Snake = ", self.queue, "; Apple = ", self.FOOD_POSITIONS) with self.model: new_pos = ((self.HEAD[0] + self.DIRECTION[0]) % self.model.height, (self.HEAD[1] + self.DIRECTION[1]) % self.model.width) if new_pos in self.FOOD_POSITIONS: self.send_message(Fap.CODE_SNAKE_ATE_APPLE) del self.FOOD_POSITIONS[new_pos] self.spawn_food(1) self.rate += self.rate_increase self.process_extras() else: x, y = self.queue.pop(0) self.model.set_pixel(x, y, self.BG_COLOR) self.process_extras(x, y) if new_pos in self.queue: # Game Over !! self.send_model() self.game_over() return else: self.HEAD = new_pos self.model.set_pixel(new_pos[0], new_pos[1], self.PIXEL_COLOR) self.queue.append(new_pos) self.send_model() rate.sleep()
def flash(self, duration=4., speed=1.5): """ Blocking and self-locking call flashing the current model on and off (mainly for game over) :param duration: Approximate duration of flashing in seconds :param rate: Rate of flashing in Hz """ rate = Rate(speed) t0 = time.time() model_id = 0 # with self._model_lock: models_bck = self.model._model.copy() model_off = False while time.time() - t0 < duration or model_off: # with self._model_lock: if model_id: self.model.set_all('black') else: self.model._model = models_bck.copy() model_id = (model_id + 1) % 2 model_off = not model_off self.send_model() rate.sleep()
class Frontage(Thread): RATE_HZ = 6 FADE_OUT_NUM_FRAMES = 20 def __init__(self, height=4, width=19): Thread.__init__(self) self.setDaemon(True) DimensionsModel() self.model = Model(height, width) self.rate = Rate(self.RATE_HZ) self.frontage_running = False self.fade_out_idx = 0 self.connection = None self.channel = None def __getitem__(self, row): return self.model.__getitem__(row) def __setitem__(self, key, value): with self.model: self.model.__setitem__(key, value) def set_all(self, r, g, b): for row in range(self.model.height): for col in range(self.model.width): self.model[row, col] = r, g, b def erase_all(self): self.set_all(0, 0, 0) def fade_out(self): self.fade_out_idx = self.FADE_OUT_NUM_FRAMES def run(self): credentials = pika.PlainCredentials( environ.get('RABBITMQ_DEFAULT_USER'), environ.get('RABBITMQ_DEFAULT_PASS')) self.connection_params = pika.ConnectionParameters( host='rabbit', credentials=credentials, connection_attempts=100, heartbeat=0) self.connection = pika.BlockingConnection(self.connection_params) ##### Receive model from apps self.channel_app_model = self.connection.channel() self.channel_app_model.exchange_declare(exchange='model', exchange_type='fanout') result = self.channel_app_model.queue_declare( exclusive=True, arguments={"x-max-length": 1}) queue_name = result.method.queue self.channel_app_model.queue_bind(exchange='model', queue=queue_name) ##### Emit model to end frame self.channel_pixels = self.connection.channel() self.channel_pixels.exchange_declare(exchange='pixels', exchange_type='fanout') self.frontage_running = True while self.frontage_running: # ASYNCHRONOUS END FRAME UPDATE LOOP method, properties, body = self.channel_app_model.basic_get( queue=queue_name, no_ack=True) if self.fade_out_idx > 1: self.model = self.model.__mul__(0.9) self.fade_out_idx -= 1 elif self.fade_out_idx == 1: self.model = self.model.__mul__(0) self.fade_out_idx = 0 elif body is not None: self.model.set_from_json(body) if self.frontage_running: self.channel_pixels.basic_publish(exchange='pixels', routing_key='', body=self.model.json()) self.rate.sleep() # Closing if self.channel is not None: self.channel.close() if self.connection is not None: self.connection.close() @property def is_running(self): return self.frontage_running def close(self): self.frontage_running = False print("==> Frontage Controler Ended. ByeBye")
class Colors(Fap): PLAYABLE = False ACTIVATED = True # GENERATORS_DICT = { 'random_flashing': gen_random_flashing, # 'sweep_async': gen_sweep_async, # 'sweep_rand': gen_sweep_rand } def __init__(self, gen, username, userid): Fap.__init__(self, username, userid) self.rate = None self.PARAMS_LIST = {} self.generator = gen def create_generator(self): # Construct all pixel generators self.generators = [] for h in range(self.model.height): line = [] for w in range(self.model.width): duration = random.randrange( 0, self.durations_max - self.durations_min) line.append( self.generator(self.durations_min, int((2.0 / self.rate.sleep_dur)), duration, self.colors)) self.generators.append(line) def load_animation(self, params): # Get uapp from Fap name, it designates a generator (not really the animation that we assign to uapp) # TODO refacto: the animation dict should contain a list of generators only, the rest are params if 'name' in params: name = params['name'] if params or params.get('uapp', False) not in self.PARAMS_LIST['uapp']: if name == 'SweepAsync': params['uapp'] = 'swipe' elif name == 'RandomFlashing': params['uapp'] = 'flashes' elif name == 'SweepRand': params['uapp'] = 'gender' return animations[params['uapp']] def process_params(self, params): c_params = self.load_animation(params) rate_hz = params.get('refresh_rate', c_params.get('rate')) self.rate = Rate(rate_hz) self.durations_min = params.get('dur_min', c_params.get('dur_min')) * rate_hz self.durations_max = params.get('dur_max', c_params.get('dur_max')) * rate_hz colors = params.get("colors", c_params.get('colors', [])) if not isinstance(colors, (tuple, list, map)): colors = [colors] self.colors = [] for c in colors: if isinstance(c, str): try: color = name_to_hsv(c.lower()) except KeyError: color = (0, 0, 0) else: color = c self.colors.append(color) def run(self, params, expires_at=None): if not self.generator: print('GENERATOR NOT DEFINED. ABORTED') return self.start_socket() self.process_params(params) self.create_generator() # Browse all pixel generators at each time while True: with self.model: for h in range(self.model.height): for w in range(self.model.width): try: color = next(self.generators[h][w]) except StopIteration: # print('Error StopIteration') pass except IndexError: # print('Error IndexError') pass else: self.model.set_pixel(h, w, color) self.send_model() self.rate.sleep()