state transitions cluster__P P cluster__P_Receiving Receiving cluster__P_Pinging Pinging cluster__P_Main Main cluster__P_Main_Connected Connected cluster__P_Main_Connected_JoiningOrJoined JoiningOrJoined cluster__P_Main_Connected_JoiningOrJoined_Joined Joined cluster__P_Main_Connected_LeavingOrLeft LeavingOrLeft cluster__P_Main_Connecting Connecting enter /input_command() __initial __initial->_P _P_Receiving_initial _P_Receiving_Receiving Receiving _P_Receiving_initial->_P_Receiving_Receiving _P_Receiving_Receiving->_P_Receiving_Receiving receive_message(msg:str)/add_message(msg,"remote_message")    _P_Pinging_initial _P_Pinging_Initial Initial _P_Pinging_initial->_P_Pinging_Initial _P_Pinging_ExpectingAnswer ExpectingAnswer _P_Pinging_Pinging Pinging _P_Pinging_ExpectingAnswer->_P_Pinging_Pinging alive    _P_Pinging_ExpectingAnswer->_P_Pinging_Initial after(2 s)^timeout /print("polling timeout... disconnect")    _P_Pinging_Pinging->_P_Pinging_ExpectingAnswer after(1 s)^network.poll    _P_Pinging_Initial->_P_Pinging_Pinging connected    _P_Main_initial _P_Main_initial->_P_Main_Connecting _P_Main_Connected->_P_Main_Connecting timeout/add_message("disconnected","info")⁏ reconnecting = true⁏    _P_Main_Connected_initial _P_Main_Connected_initial->_P_Main_Connected_LeavingOrLeft _P_Main_Connected_H H _P_Main_Connected_JoiningOrJoined_initial _P_Main_Connected_JoiningOrJoined_Joining Joining enter ^network.join _P_Main_Connected_JoiningOrJoined_initial->_P_Main_Connected_JoiningOrJoined_Joining _P_Main_Connected_JoiningOrJoined_Joined_H H _P_Main_Connected_JoiningOrJoined_Joining->_P_Main_Connected_JoiningOrJoined_Joined_H joined/add_message("joined room " + int_to_str(room_number),"info")    _P_Main_Connected_JoiningOrJoined_Joined_initial _P_Main_Connected_JoiningOrJoined_Joined_Initial Initial _P_Main_Connected_JoiningOrJoined_Joined_initial->_P_Main_Connected_JoiningOrJoined_Joined_Initial _P_Main_Connected_JoiningOrJoined_Joined_EnteringMessage EnteringMessage enter /input_msg() _P_Main_Connected_JoiningOrJoined_Joined_EnteringMessage->_P_Main_Connected_JoiningOrJoined_Joined_EnteringMessage input(char:str) [is_backspace(char)]/remove_last_in_buffer()    _P_Main_Connected_JoiningOrJoined_Joined_EnteringMessage->_P_Main_Connected_JoiningOrJoined_Joined_EnteringMessage input(char:str)/append_to_buffer(char)    _P_Main_Connected_JoiningOrJoined_Joined_EnteringMessage->_P_Main_Connected_JoiningOrJoined_Joined_Initial input(char:str) [is_enter(char)]^network.send_message /add_message(get_buffer(),"local_message")⁏ clear_input()⁏ input_command()⁏    _P_Main_Connected_JoiningOrJoined_Joined_Initial->_P_Main_Connected_JoiningOrJoined_Joined_EnteringMessage input(char:str) [char == "m"]    _P_Main_Connected_LeavingOrLeft_Leaving Leaving _P_Main_Connected_JoiningOrJoined_Joined_Initial->_P_Main_Connected_LeavingOrLeft_Leaving input(char:str) [char == "l"]^network.leave /input_command()    _P_Main_Connected_LeavingOrLeft_initial _P_Main_Connected_LeavingOrLeft_NotJoined NotJoined _P_Main_Connected_LeavingOrLeft_initial->_P_Main_Connected_LeavingOrLeft_NotJoined _P_Main_Connected_LeavingOrLeft_Leaving->_P_Main_Connected_LeavingOrLeft_NotJoined left/add_message("left room","info")    _P_Main_Connected_LeavingOrLeft_GettingRoomNumber GettingRoomNumber _P_Main_Connected_LeavingOrLeft_GettingRoomNumber->_P_Main_Connected_JoiningOrJoined input(char:str) [is_enter(char)]/room_number = stoi(get_buffer())⁏ clear_input()⁏ input_command()⁏    _P_Main_Connected_LeavingOrLeft_GettingRoomNumber->_P_Main_Connected_LeavingOrLeft_GettingRoomNumber input(char:str) [is_backspace(char)]/remove_last_in_buffer()    _P_Main_Connected_LeavingOrLeft_GettingRoomNumber->_P_Main_Connected_LeavingOrLeft_GettingRoomNumber input(char:str) [is_numerical(char)]/append_to_buffer(char)    _P_Main_Connected_LeavingOrLeft_GettingRoomNumber->_P_Main_Connected_LeavingOrLeft_GettingRoomNumber input(char:str) [not is_numerical(char)]/add_message("only numerical input allowed!","warning")    _P_Main_Connected_LeavingOrLeft_NotJoined->_P_Main_Connected_LeavingOrLeft_GettingRoomNumber input(char:str) [char == "j"]/input_join()    _P_Main_Connecting_initial _P_Main_Connecting_Initial Initial _P_Main_Connecting_initial->_P_Main_Connecting_Initial _P_Main_Connecting_TryingConnect TryingConnect _P_Main_Connecting_TryingConnect->_P_Main_Connected_H connected/add_message("connected to server " + get_server(curr_server),"info")    _P_Main_Connecting_TryingConnect->_P_Main_Connecting_Initial after(5 s)/add_message("unable to connect to server " + get_server(curr_server),"info")⁏ if (not reconnecting) [[curr_server = (curr_server + 1) % get_nr_of_servers()⁏ ]]⁏    _P_Main_Connecting_Initial->_P_Main_Connecting_TryingConnect after(100 ms)/add_message("trying to connect to server " + get_server(curr_server),"info") ^network.connect