Ejemplo n.º 1
0
    def __init__(self):
        super(ResultSaver, self).__init__()

        self._stop = subject.Subject()
        self.config = config.SettingAccessor(self.config_prefix)
        self.subjects: Subjects = services.service_provider.SubjectProvider().get_or_create_instance(None)
        self.saving_scheduler = scheduler.NewThreadScheduler()
        self.subjects.image_producer.pipe(
            operators.observe_on(self.saving_scheduler),
            operators.filter(self.config_enabled_filter("save_images")),
            operators.take_until(self._stop),
        ).subscribe(ErrorToConsoleObserver(self.save_image))
        self.subjects.detection_result.pipe(
            operators.observe_on(self.saving_scheduler),
            operators.filter(self.config_enabled_filter("save_labels")),
            operators.take_until(self._stop),
        ).subscribe(ErrorToConsoleObserver(self.save_labels))
        self.subjects.add_to_timeline.pipe(
            operators.observe_on(self.saving_scheduler),
            operators.filter(self.config_enabled_filter("save_events")),
            operators.take_until(self._stop),
        ).subscribe(ErrorToConsoleObserver(self.save_timeline_events))

        config.setting_updated_channel.pipe(
            operators.filter(self._directory_filter),
            operators.take_until(self._stop),
        ).subscribe(ErrorToConsoleObserver(lambda x: self.initialize_saving_directory()))

        self.initialize_saving_directory()
Ejemplo n.º 2
0
    def start(self):
        if not self.subjects.analyzer_connected.value:
            if not self.analyzer_not_connected_prompt():
                return

        qt_scheduler = QtScheduler(QtCore)

        # this sequence is auto-back-pressured
        observable = self.request_media_file(qt_scheduler).pipe(
            # list of files
            operators.observe_on(scheduler.NewThreadScheduler()),
            # The following sequence will be run on a new thread.
            operators.flat_map(rx.from_list),
            # observable of files.
            self.load_file_operator(
            ),  # When back pressure, this one will block.
            # observable of frames (AcquiredImage). This operation will be blocked if the downstream is blocked.
            operators.take_until(self._stop),
        ).subscribe(
            ErrorToConsoleObserver(on_next=self.next_image,
                                   on_error=self._catch))

        self.subjects.analyzer_back_pressure_detected.pipe(
            operators.take_until(self._stop), ).subscribe(
                self.notify_back_pressure_changed)
        super().start()
Ejemplo n.º 3
0
    def configure_subscriptions(self):
        self.subjects.detection_result.pipe(
            operators.buffer_with_count(self.config["group_size"]),
            operators.take_until(self._stop),
        ).subscribe(ErrorToConsoleObserver(self.process_distribution_data))

        self.subjects.sample_image_data.pipe(operators.take_until(
            self._stop), ).subscribe(
                ErrorToConsoleObserver(self.render_sample_image))
Ejemplo n.º 4
0
    def enqueue(self,
                observable: Observable,
                group: str = 'default-group',
                retries: int = 0,
                description: str = None) -> Observable:
        def log_status(status):
            logging.debug(
                str({
                    'WorkQueue': str(self),
                    'group': group,
                    status: description
                }))

        log_status('ENQUEUED')
        output = Subject()
        errors = Subject()
        output_finalized = Subject()

        def handle_error(e, _):
            log_status('FAILED')
            errors.on_next(e)
            return empty()

        def set_output_finalized():
            output_finalized.on_next(True)

        work = of(True).pipe(
            do_action(lambda _: log_status('STARTED')),
            take_until(output_finalized),
            flat_map(lambda _: observable.pipe(
                map(lambda value: of({
                    'value': value,
                    'output': output
                })),
                retry_with_backoff(
                    retries=retries,
                    description='{}.enqueue(group={}, description={})'.format(
                        self, group, description)),
                catch(handler=handle_error), take_until(output_finalized),
                take_until_disposed())),
            concat(of(of({
                'completed': True,
                'output': output
            }))), finally_action(lambda: log_status('COMPLETED')))

        self._queue.on_next({'work': work, 'group': group})

        return output.pipe(observe_on(self.request_scheduler),
                           throw_when(errors),
                           take_while(lambda r: not r.get('completed')),
                           map(lambda r: r.get('value')),
                           finally_action(set_output_finalized))
Ejemplo n.º 5
0
    def _initialize_drag(self, ui: FrameUI):
        offset = rx.merge(self.on_drag_start, self.on_drag).pipe(
            ops.filter(
                lambda e: self.draggable and e.button == MouseButton.LEFT),
            ops.filter(lambda e: ui.allow_drag(self, self.position_of(e))),
            ops.filter(lambda e: not self.resizable or ui.resize_handle_at(
                self, e.position) == Nothing), ops.map(lambda e: e.position),
            ops.pairwise(), ops.map(lambda v: v[1] - v[0]),
            ops.take_until(
                self.on_drag_end.pipe(
                    ops.filter(lambda e: e.button == MouseButton.LEFT))),
            ops.repeat(), ops.take_until(self.on_dispose))

        self._drag_listener = offset.subscribe(
            self.move_by, on_error=self.context.error_handler)
Ejemplo n.º 6
0
 def test_without_bp(self):
     self.source.pipe(
         operators.do_action(lambda x: print(f"Producing {x}")),
         operators.map(self.slow_op),
         operators.do_action(self.stop),
         operators.take_until(self._stop),
     ).run()
Ejemplo n.º 7
0
 def test_with_observe_on(self):
     self.source.pipe(
         operators.do_action(lambda x: print(f"Producing {x}")),
         operators.observe_on(NewThreadScheduler()),
         operators.map(self.slow_op),
         operators.do_action(self.stop),
         operators.take_until(self._stop),
     ).run()
Ejemplo n.º 8
0
 def test_with_buffer(self):
     self.source.pipe(
         operators.do_action(lambda x: print(f"Producing {x}")),
         bp_operator(BackPressure.BUFFER),
         operators.map(self.slow_op),
         operators.do_action(self.stop),
         operators.take_until(self._stop),
     ).run()
Ejemplo n.º 9
0
 def event_for(button: MouseButton) -> Observable:
     return self.on_button_release(button).pipe(
         ops.map(lambda _: rx.concat(
             rx.of(self.position),
             rx.never().pipe(
                 ops.take_until(self.on_button_press(button))))),
         ops.exclusive(),
         ops.map(lambda p: MouseUpEvent(self.context, p, button)))
Ejemplo n.º 10
0
 def test_attach_size(self):
     self.source.pipe(
         operators.do_action(lambda x: print(f"Producing {x}")),
         bp_drop_operator_attach_size(3),
         operators.do_action(print),
         operators.map(self.slow_op),
         operators.do_action(self.stop),
         operators.take_until(self._stop),
     ).run()
Ejemplo n.º 11
0
    def __init__(self, context: Context, layout: Optional[Layout] = None):
        super().__init__(context, layout)

        def on_resolution_change(size: Dimension):
            self.bounds = Bounds(0, 0, size.width, size.height)

        context.observe("window_size") \
            .pipe(ops.take_until(self.on_dispose)) \
            .subscribe(on_resolution_change, on_error=self.error_handler)
Ejemplo n.º 12
0
    def on_drag(self) -> Observable:
        mouse = MouseInput.input(self)
        position = mouse.observe("position")

        return self.on_drag_start.pipe(
            ops.map(lambda e: position.pipe(
                ops.skip(1), ops.map(lambda p: DragEvent(self, p, e.button)),
                ops.take_until(mouse.on_button_release(e.button)))),
            ops.exclusive())
Ejemplo n.º 13
0
    def __init__(self, context: Context):
        super().__init__(context)

        def dispatch(event: PositionalEvent) -> None:
            self.context.dispatcher_at(
                event.position).map(lambda d: d.dispatch_event(event))

        self._dispatchers = rx.merge(*self.positional_events) \
            .pipe(ops.take_until(self.on_dispose)) \
            .subscribe(dispatch, on_error=self.error_handler)
Ejemplo n.º 14
0
    def on_drag_leave(self) -> Observable:
        mouse = MouseInput.input(self)
        position = mouse.observe("position")

        from_inside = self.on_mouse_down.pipe(
            ops.map(lambda e: position.pipe(
                ops.filter(lambda p: not self.bounds.contains(p - self.offset)
                           ), ops.take(1), ops.map(lambda p: (p, e.button)),
                ops.take_until(mouse.on_button_release(e.button)))),
            ops.exclusive())

        from_outside = self.on_drag_over.pipe(
            ops.map(lambda e: self.on_mouse_out.pipe(
                ops.take(1), ops.map(lambda o: (o.position, e.button)),
                ops.take_until(mouse.on_button_release(e.button)))),
            ops.exclusive())

        return rx.merge(from_inside, from_outside).pipe(
            ops.map(lambda e: DragLeaveEvent(self, e[0], e[1])))
Ejemplo n.º 15
0
    def on_drag_start(self) -> Observable:
        mouse = MouseInput.input(self)
        position = mouse.observe("position")

        return self.on_mouse_down.pipe(
            ops.map(lambda e: position.pipe(
                ops.take(1),
                ops.map(lambda _: DragStartEvent(self, e.position, e.button)),
                ops.take_until(mouse.on_button_release(e.button)))),
            ops.exclusive())
Ejemplo n.º 16
0
 def start(self):
     self.fps = self.config["fps"]
     rx.interval(1 / self.fps).pipe(
         operators.map(lambda x: self.generate_image()),
         operators.map(
             lambda arr: AcquiredImage(arr,
                                       datetime.now().timestamp())),
         operators.take_until(self._stop),
     ).subscribe(ErrorToConsoleObserver(self.next_image))
     self.running = True
     super().start()
Ejemplo n.º 17
0
    def on_drag_over(self) -> Observable:
        mouse = MouseInput.input(self)

        return mouse.on_mouse_down.pipe(
            ops.filter(
                lambda e: not self.bounds.contains(e.position - self.offset)),
            ops.map(lambda e: self.on_mouse_over.pipe(
                ops.map(lambda o: (o.position, e.button)),
                ops.take_until(mouse.on_button_release(e.button)))),
            ops.exclusive(),
            ops.map(lambda e: DragOverEvent(self, e[0], e[1])))
Ejemplo n.º 18
0
 def start(self):
     if self.is_running():
         self.logger.warning(
             "GRPC remote inference server is already connected.")
         return
     self.inference_comm.connection_chan.pipe(
         operators.take_until(self._stop)).subscribe(
             ErrorToConsoleObserver(self.configure_subscriptions))
     self.inference_comm.connect_to_grpc_server(self.config["ip"],
                                                self.config["port"])
     super(RemoteAnalyzer, self).start()
Ejemplo n.º 19
0
    def _initialize_resize(self, ui: FrameUI):
        mouse = MouseInput.input(self)

        bounds = self.on_drag_start.pipe(
            ops.filter(
                lambda e: self.resizable and e.button == MouseButton.LEFT),
            ops.map(lambda e: ui.resize_handle_at(
                self, e.position).map(lambda v: Frame._ResizeState(
                    v, e.position, self.bounds, self.minimum_size))),
            ops.map(lambda v: v.map(rx.of).value_or(rx.empty())),
            ops.switch_latest(),
            ops.map(lambda s: mouse.on_mouse_move.pipe(
                ops.map(lambda e: self._bounds_for_state(s, e.position)),
                ops.take_until(mouse.on_button_release(MouseButton.LEFT)))),
            ops.switch_latest(), ops.take_until(self.on_dispose))

        def set_bounds(b: Bounds) -> None:
            self.bounds = b

        self._resize_listener = bounds.subscribe(
            set_bounds, on_error=self.context.error_handler)
Ejemplo n.º 20
0
 def _simex_configure_subscription(self, x=None):
     self.subjects.image_producer.pipe(
         operators.observe_on(self.execution_thread),
         operators.map(lambda acquired_image: acquired_image.image
                       ),  # pluck the image array
         operators.map(lambda im: np.median(im)),
         operators.buffer_with_count(self.config["buffer_count"]),
         operators.map(lambda medians: np.mean(medians)),
         operators.take_until(self._stop)
     ).subscribe(
         ErrorToConsoleObserver(lambda t: self.instance.request_port_update(
             OutputPorts.BRIGHTNESS.value, np.asarray(t, dtype=np.float64)).
                                subscribe(ErrorToConsoleObserver())))
Ejemplo n.º 21
0
    def on_mouse_over(self) -> Observable:
        position = MouseInput.input(self).observe("position")
        local_pos = position.pipe(ops.map(lambda p: p - self.offset))

        return self.on_mouse_move.pipe(
            ops.map(lambda e: e.position),
            ops.map(lambda p: rx.concat(
                rx.of(p),
                rx.never().pipe(
                    ops.take_until(
                        local_pos.pipe(
                            ops.filter(lambda l: not self.bounds.contains(l)))
                    )))), ops.exclusive(),
            ops.map(lambda p: MouseOverEvent(self, p)))
Ejemplo n.º 22
0
    def start(self):
        # report more image when back pressure
        self.subjects.image_producer.pipe(
            operators.observe_on(self.scheduler),
            operators.combine_latest(
                self.subjects.analyzer_back_pressure_detected),
            operators.filter(
                lambda x: x[1]),  # only operate when back pressure
            operators.buffer_with_time(1.0),  # in 1 sec
            operators.filter(lambda x: len(x) > 3),  # more than 3 emission
            operators.throttle_first(3.0),  # report every 3 seconds
            operators.take_until(self._stop),
        ).subscribe(self.report_back_pressure_emission)

        self.subjects.image_producer.pipe(
            operators.observe_on(
                self.scheduler),  # prevent blocking the upstream subject
            operators.filter(self.back_pressure_barrier),
            operators.buffer_with_count(5),
            bp_drop_report_full(self.subjects.analyzer_back_pressure_detected,
                                3, 1),
            operators.take_until(self._stop),
        ).subscribe(ErrorToConsoleObserver(self.produce_fake_analyze_data))
        super(TestAnalyzer, self).start()
Ejemplo n.º 23
0
        def schedule_emit_next_until(until: subject.Subject):
            stop_emitting = False

            def _action(sch: rx.typing.Scheduler, state=None):
                emit_next()

            def until_on_next(v):
                nonlocal stop_emitting
                stop_emitting = True

            until.pipe(operators.take_until(_stop)).subscribe(until_on_next,
                                                              scheduler=sch)

            if not stop_emitting:
                sch.schedule(_action)
Ejemplo n.º 24
0
    def play_step(self, step, cancel):
        interval = rx.interval(0.1)
        interval_steps = rx.just(step).pipe(
            ops.flat_map(lambda step: interval.pipe(ops.map(lambda _: step))))

        step_done = interval_steps.pipe(
            ops.filter(lambda step: self.player.position() >= step.step_end),
            ops.do_action(
                lambda step: self.player.set_position(step.loop_start)),
            ops.take(1))

        loop_done = interval_steps.pipe(
            ops.filter(lambda step: self.player.position() >= step.loop_end),
            ops.do_action(
                lambda step: self.player.set_position(step.loop_start)),
            ops.take_until(cancel.pipe(ops.skip(1))))

        return step_done.pipe(ops.merge(loop_done))
Ejemplo n.º 25
0
        def handleSubscription(msg: RxImpMessage):
            currentCount = 0

            def on_next(next):
                nonlocal currentCount
                nextMsg = RxImpMessage(topic=msg.topic,
                                       count=currentCount,
                                       rx_state=RxImpMessage.STATE_NEXT,
                                       payload=json.dumps(next),
                                       id=msg.id)
                currentCount += 1
                self._out.on_next(nextMsg)

            def on_error(error):
                nonlocal currentCount
                errorMsg = RxImpMessage(topic=msg.topic,
                                        count=currentCount,
                                        rx_state=RxImpMessage.STATE_ERROR,
                                        payload=json.dumps(error),
                                        id=msg.id)
                currentCount += 1
                self._out.on_next(errorMsg)

            def on_complete():
                nonlocal currentCount
                completeMsg = RxImpMessage(
                    topic=msg.topic,
                    count=currentCount,
                    rx_state=RxImpMessage.STATE_COMPLETE,
                    payload=None,
                    id=msg.id)
                currentCount += 1
                self._out.on_next(completeMsg)

            handler(json.loads(msg.payload)).pipe(
                take_until(
                    self._in.pipe(
                        filter(lambda x: x.rx_state ==
                               RxImpMessage.STATE_DISPOSE),
                        filter(lambda x: x.id == msg.id), take(1)))).subscribe(
                            on_next=lambda x: on_next(x),
                            on_error=lambda x: on_error(x),
                            on_completed=lambda: on_complete())
Ejemplo n.º 26
0
    def __init__(self,
                 toolkit: Toolkit,
                 look_and_feel: Optional[LookAndFeel] = None,
                 font_options: Optional[FontOptions] = None,
                 window_manager: Optional[WindowManager] = None,
                 error_handler: Optional[ErrorHandler] = None) -> None:
        if toolkit is None:
            raise ValueError("Argument 'toolkit' is required.")

        super().__init__()

        from alleycat.ui import WindowManager
        from alleycat.ui.glass import GlassLookAndFeel

        self._toolkit = toolkit

        self._look_and_feel = Maybe.from_optional(look_and_feel).or_else_call(lambda: GlassLookAndFeel(toolkit))
        self._font_options = Maybe.from_optional(font_options).or_else_call(
            lambda: FontOptions(antialias=ANTIALIAS_SUBPIXEL, hint_style=HINT_STYLE_FULL))

        self._error_handler = Maybe.from_optional(error_handler).value_or(toolkit.error_handler)

        self._window_manager = Maybe.from_optional(window_manager) \
            .or_else_call(lambda: WindowManager(self.error_handler))

        inputs = toolkit.create_inputs(self)

        assert inputs is not None

        self._inputs = {i.id: i for i in inputs}
        self._pollers = [i for i in inputs if isinstance(i, EventLoopAware)]

        # noinspection PyTypeChecker
        self.surface = self.observe("window_size").pipe(ops.map(self.toolkit.create_surface))

        old_surface = self.observe("surface").pipe(
            ops.pairwise(),
            ops.map(lambda s: s[0]),
            ops.take_until(self.on_dispose))

        old_surface.subscribe(Surface.finish, on_error=self.error_handler)
Ejemplo n.º 27
0
    def __init__(self, context: Context, visible: bool = True) -> None:
        if context is None:
            raise ValueError("Argument 'context' is required.")

        # noinspection PyTypeChecker
        self.visible = visible

        self._context = context
        self._valid = False
        self._ui = self.create_ui()

        assert self._ui is not None

        super().__init__()

        self.validate()

        self.ui \
            .on_invalidate(self) \
            .pipe(ops.take_until(self.on_dispose)) \
            .subscribe(lambda _: self.invalidate(), on_error=self.error_handler)
Ejemplo n.º 28
0
    def downstream_subscribe(observer: rx.core.Observer,
                             sch: rx.typing.Scheduler = None):
        def emit_next():
            if len(buffer):
                observer.on_next(buffer.pop(0))
            else:
                if _upstream_completed:
                    observer.on_completed()

        def schedule_emit_next_until(until: subject.Subject):
            stop_emitting = False

            def _action(sch: rx.typing.Scheduler, state=None):
                emit_next()

            def until_on_next(v):
                nonlocal stop_emitting
                stop_emitting = True

            until.pipe(operators.take_until(_stop)).subscribe(until_on_next,
                                                              scheduler=sch)

            if not stop_emitting:
                sch.schedule(_action)

        def should_stop_updated(val: bool):
            if val:
                # should stop, do nothing until next message
                pass
            else:
                # normal operation
                # Cannot guarantee that the should_stop will emit every time the value is received.
                schedule_emit_next_until(should_stop)

        should_stop.pipe(
            operators.take_until(_stop)).subscribe(should_stop_updated)
Ejemplo n.º 29
0
    def configure_subscriptions(self, connected):
        if connected:
            self.subjects.image_producer.pipe(
                operators.observe_on(self.feed_scheduler),
                operators.buffer_with_count(self.batch_size),
                bp_operator(BackPressure.DROP, 5),
                operators.take_until(self._stop),
            ).subscribe(ErrorToConsoleObserver(self.feed_image))

            self.inference_comm.back_pressure_chan.pipe(
                operators.subscribe_on(self.process_scheduler),
                operators.take_until(self._stop)).subscribe(
                    ErrorToConsoleObserver(self.update_back_pressure_status))

            # report error when image source is still producing when back pressuring
            self.subjects.analyzer_back_pressure_detected.pipe(
                operators.combine_latest(self.subjects.image_producer),
                operators.filter(lambda x: x[0]),
                operators.throttle_first(1.0),
                operators.take_until(self._stop),
            ).subscribe(
                ErrorToConsoleObserver(lambda x: self.logger.warning(
                    "Image is feeding while back-pressure is detected. Please slow down the FPS"
                )))

            self.inference_comm.result_chan.pipe(
                operators.subscribe_on(self.process_scheduler),
                operators.take_until(self._stop)).subscribe(
                    ErrorToConsoleObserver(self.result_processing))

            self.inference_comm.error_chan.pipe(
                operators.take_until(self._stop)).subscribe(
                    ErrorToConsoleObserver(lambda err: self.logger.error(err)))
            self.inference_comm.connection_chan.pipe(
                operators.take_until(self._stop)).subscribe(
                    ErrorToConsoleObserver(lambda connected: self.logger.info(
                        "GRPC Remote analyzer connected" if connected else
                        "GRPC Remote analyzer disconnected")))
            self.inference_comm.stats_chan.take_until(self._stop).subscribe(
                ErrorToConsoleObserver(lambda x: self.logger.info(
                    f"Processed {x.frame} frames. Average {x.processTime / x.frame} secs"
                )))
Ejemplo n.º 30
0
# 위와 다른 점: args 로 생성한다.
print('--')

# 마블에서 옵저버블 생성 하기
# 타이밍을 제어 할 수 있다.
from rx.testing import marbles, TestScheduler

scheduler = TestScheduler()
ts = 0.1
rx.from_marbles('--(a1)-(b2)---(c3)|', timespan=ts).subscribe(print_value)
rx.from_marbles('(a6)---(b5)(c4)|', timespan=ts).subscribe(print_value)
time.sleep(2)
print('--')

# Interval 을 이용한 옵저버블 생성
rx.interval(0.3).pipe(ops.take_until(rx.timer(3))).subscribe(print_value)
time.sleep(4)
print('--')

# 버퍼
print('-- buffer')
rx.from_(range(2000)).pipe(ops.buffer(
    rx.interval(0.001))).subscribe(on_next=lambda buffer: print(
        '# of items in buffer {}'.format(len(buffer))))
time.sleep(2)

print('-- buffer with count')
rx.from_(range(10)).pipe(ops.buffer_with_count(3)).subscribe(print_value)

print('-- buffer with time')
rx.interval(1).pipe(