Example #1
0
def main(args: argparse.Namespace):
    loadfile: Path
    if os.path.isabs(args.loadfile):
        loadfile = Path(args.loadfile)
    else:
        # Take paths relative to 'data/saves/'
        loadfile = common.savefile(args.loadfile)

    physics_engine = physics.PhysicsEngine(common.load_savefile(loadfile))
    initial_state = physics_engine.get_state()

    gui = flight_gui.FlightGui(initial_state,
                               title=name,
                               running_as_mirror=False)
    atexit.register(gui.shutdown)

    if args.flamegraph:
        common.start_flamegraphing()
    if args.profile:
        common.start_profiling()

    while True:
        state = physics_engine.get_state()

        # If we have any commands, process them so the simthread has as
        # much time as possible to restart before next update.
        physics_engine.handle_requests(gui.pop_commands())

        gui.draw(state)
        gui.rate(common.FRAMERATE)
Example #2
0
    def __init__(self, client: protos.Command.ClientType, hostname: str):
        self.channel = grpc.insecure_channel(f'{hostname}:{DEFAULT_PORT}')
        self.stub = grpc_stubs.StateServerStub(self.channel)
        self.client_type = client

        initial_state = PhysicsState(
            None,
            self.stub.get_physical_state(
                iter([Request(ident=Request.NOOP, client=self.client_type)])))

        self._caching_physics_engine = physics.PhysicsEngine(initial_state)
        self._time_of_next_network_update = 0.0
Example #3
0
def main(args: argparse.Namespace):
    # Before you make changes to this function, keep in mind that this function
    # starts a GRPC server that runs in a separate thread!
    state_server = network.StateServer()

    loadfile: Path
    if os.path.isabs(args.loadfile):
        loadfile = Path(args.loadfile)
    else:
        # Take paths relative to 'data/saves/'
        loadfile = common.savefile(args.loadfile)

    physics_engine = physics.PhysicsEngine(common.load_savefile(loadfile))
    initial_state = physics_engine.get_state()

    TICKS_BETWEEN_CLIENT_LIST_REFRESHES = 150
    ticks_until_next_client_list_refresh = 0

    server = grpc.server(
        concurrent.futures.ThreadPoolExecutor(max_workers=4))
    atexit.register(lambda: server.stop(grace=2))
    grpc_stubs.add_StateServerServicer_to_server(state_server, server)
    server.add_insecure_port(f'[::]:{network.DEFAULT_PORT}')
    state_server.notify_state_change(initial_state.as_proto())
    server.start()  # This doesn't block!

    gui = ServerGui()

    try:
        if args.flamegraph:
            common.start_flamegraphing()
        if args.profile:
            common.start_profiling()

        while True:
            # If we have any commands, process them immediately so input lag
            # is minimized.
            commands = state_server.pop_commands() + gui.pop_commands()
            physics_engine.handle_requests(commands)

            state = physics_engine.get_state()
            state_server.notify_state_change(state.as_proto())

            if ticks_until_next_client_list_refresh == 0:
                ticks_until_next_client_list_refresh = \
                    TICKS_BETWEEN_CLIENT_LIST_REFRESHES
                state_server.refresh_client_list()
            ticks_until_next_client_list_refresh -= 1

            gui.update(state, state_server.addr_to_connected_clients.values())
    finally:
        server.stop(grace=1)
Example #4
0
def main(args: argparse.Namespace):
    log.info(f'Connecting to physics server {args.physics_server}.')
    time_of_next_network_update = 0.0
    lead_server_connection = network.StateClient(Request.HAB_FLIGHT,
                                                 args.physics_server)
    state = lead_server_connection.get_state()
    physics_engine = physics.PhysicsEngine(state)

    gui = flight_gui.FlightGui(state, title=name, running_as_mirror=False)
    atexit.register(gui.shutdown)

    while True:
        gui.draw(state)

        user_commands = gui.pop_commands()
        current_time = time.monotonic()

        # If there are user commands or we've gone a while since our last
        # contact with the physics server, request an update.
        if user_commands or current_time > time_of_next_network_update:
            # Our state is stale, get the latest update
            # TODO: what if this fails? Do anything smarter than an exception?
            state = lead_server_connection.get_state(user_commands)
            physics_engine.set_state(state)
            if len(user_commands) == 0:
                time_of_next_network_update = (
                    current_time + common.TIME_BETWEEN_NETWORK_UPDATES)
            else:
                # If we sent a user command, still ask for an update soon so
                # the user input can be reflected in hab flight's GUI as soon
                # as possible.
                # Magic number alert! The constant we add should be enough that
                # the physics server has had enough time to simulate the effect
                # of our input, but we should minimize the constant to minimize
                # input lag.
                time_of_next_network_update = current_time + 0.15
        else:
            state = physics_engine.get_state()

        gui.rate(common.FRAMERATE)
Example #5
0
def main(args: argparse.Namespace):
    time_of_last_network_update = 0.0
    networking = True  # Whether data is requested over the network

    log.info(f'Connecting to physics server {args.physics_server}.')
    lead_server_connection = network.StateClient(Request.MC_FLIGHT,
                                                 args.physics_server)
    state = lead_server_connection.get_state()
    physics_engine = physics.PhysicsEngine(state)

    gui = flight_gui.FlightGui(state, title=name, running_as_mirror=True)
    atexit.register(gui.shutdown)

    while True:
        old_networking = networking
        networking = gui.requesting_read_from_physics_server()
        if old_networking != networking:
            log.info(('STARTED' if networking else 'STOPPED') +
                     ' networking with the physics server at ' +
                     args.physics_server)

        if (networking and time.monotonic() - time_of_last_network_update >
                common.TIME_BETWEEN_NETWORK_UPDATES):
            # Our state is stale, get the latest update
            # TODO: what if this fails? Set networking to False?
            state = lead_server_connection.get_state()
            physics_engine.set_state(state)
            time_of_last_network_update = time.monotonic()
        else:
            state = physics_engine.get_state()

        gui.draw(state)
        if not networking:
            # When we're not networking, allow user input.
            physics_engine.handle_requests(gui.pop_commands())
        gui.rate(common.FRAMERATE)
Example #6
0
 def __init__(self, savefile):
     self.physics_engine = physics.PhysicsEngine(
         common.load_savefile(common.savefile(savefile)))