Adding frame showing to the moving action.

This commit is contained in:
Sergiotarxz 2023-06-23 02:31:11 +02:00
parent 15c9d2f6fd
commit 76a471a655
10 changed files with 124 additions and 70 deletions

View File

@ -42,6 +42,7 @@ export default function Game (props: GameProps): JSX.Element {
const [error, setError] = React.useState<string | null>(null) const [error, setError] = React.useState<string | null>(null)
const [scrollLog, setScrollLog] = React.useState<number | null>(null) const [scrollLog, setScrollLog] = React.useState<number | null>(null)
const [movingTo, setMovingTo] = React.useState<Location | null>(null) const [movingTo, setMovingTo] = React.useState<Location | null>(null)
const [remainingFrames, setRemainingFrames] = React.useState<number | null>(null)
const logPresentationRef = React.useRef<HTMLDivElement>(null) const logPresentationRef = React.useRef<HTMLDivElement>(null)
window.setTimeout(() => { window.setTimeout(() => {
setWebsocket((websocket): WebSocket | null => { setWebsocket((websocket): WebSocket | null => {
@ -66,7 +67,7 @@ export default function Game (props: GameProps): JSX.Element {
const inputPackets = new InputPackets(setTeamPJs, const inputPackets = new InputPackets(setTeamPJs,
setCurrentLocation, setConnectedLocations, setCurrentLocation, setConnectedLocations,
logLines, setLogLines, setError, setScrollLog, logLines, setLogLines, setError, setScrollLog,
logPresentationRef, setMovingTo) logPresentationRef, setMovingTo, setRemainingFrames)
webSocket.onmessage = (event) => { webSocket.onmessage = (event) => {
const packet = JSON.parse(event.data) const packet = JSON.parse(event.data)
inputPackets.handle(packet) inputPackets.handle(packet)
@ -91,7 +92,8 @@ export default function Game (props: GameProps): JSX.Element {
logLines={logLines} logLines={logLines}
websocket={websocket} websocket={websocket}
logPresentationRef={logPresentationRef} logPresentationRef={logPresentationRef}
movingTo={movingTo}/> movingTo={movingTo}
remainingFrames={remainingFrames}/>
<BottomPanel/> <BottomPanel/>
</> </>
) )

View File

@ -16,6 +16,7 @@ interface UpperPanelProps {
websocket: WebSocket | null websocket: WebSocket | null
logPresentationRef: React.RefObject<HTMLDivElement> logPresentationRef: React.RefObject<HTMLDivElement>
movingTo: Location | null movingTo: Location | null
remainingFrames: number | null
} }
export default function UpperPanel (props: UpperPanelProps): JSX.Element { export default function UpperPanel (props: UpperPanelProps): JSX.Element {
@ -64,6 +65,7 @@ export default function UpperPanel (props: UpperPanelProps): JSX.Element {
</> </>
) )
} }
function showLocationMenuHeaderText (): JSX.Element { function showLocationMenuHeaderText (): JSX.Element {
if (currentLocation === null) { if (currentLocation === null) {
return <></> return <></>
@ -80,6 +82,18 @@ export default function UpperPanel (props: UpperPanelProps): JSX.Element {
</p> </p>
} }
function showRemainingFrames (): JSX.Element {
if (props.movingTo === null) {
return <></>
}
if (props.remainingFrames === null) {
return <></>
}
return (
<p>Te quedan <b>{props.remainingFrames}</b> frames para terminar la acción.</p>
)
}
return ( return (
<Presentation> <Presentation>
<PresentationItem> <PresentationItem>
@ -96,6 +110,9 @@ export default function UpperPanel (props: UpperPanelProps): JSX.Element {
{ {
showLocationMenuHeaderText() showLocationMenuHeaderText()
} }
{
showRemainingFrames()
}
{ {
availableLocationsToMove() availableLocationsToMove()
} }

View File

@ -16,6 +16,7 @@ type SetScrollLogCallback = (set: number | null) => number | null
type SetScrollLog = (set: number | null | SetScrollLogCallback) => void type SetScrollLog = (set: number | null | SetScrollLogCallback) => void
type LogPresentationRef = React.RefObject<HTMLDivElement> type LogPresentationRef = React.RefObject<HTMLDivElement>
type SetMovingTo = (set: Location | null) => void type SetMovingTo = (set: Location | null) => void
type SetRemainingFrames = (set: number | null) => void
interface Packet { interface Packet {
command: string command: string
@ -35,6 +36,7 @@ export default class InputPackets {
setScrollLog: SetScrollLog setScrollLog: SetScrollLog
logPresentationRef: LogPresentationRef logPresentationRef: LogPresentationRef
setMovingTo: SetMovingTo setMovingTo: SetMovingTo
setRemainingFrames: SetRemainingFrames
constructor (setTeamPJs: SetTeamPJs, constructor (setTeamPJs: SetTeamPJs,
setCurrentLocation: SetCurrentLocation, setCurrentLocation: SetCurrentLocation,
setConnectedLocations: SetConnectedLocations, setConnectedLocations: SetConnectedLocations,
@ -43,7 +45,8 @@ export default class InputPackets {
setError: SetError, setError: SetError,
setScrollLog: SetScrollLog, setScrollLog: SetScrollLog,
logPresentationRef: LogPresentationRef, logPresentationRef: LogPresentationRef,
setMovingTo: SetMovingTo) { setMovingTo: SetMovingTo,
setRemainingFrames: SetRemainingFrames) {
this.setTeamPJs = setTeamPJs this.setTeamPJs = setTeamPJs
this.setCurrentLocation = setCurrentLocation this.setCurrentLocation = setCurrentLocation
this.setConnectedLocations = setConnectedLocations this.setConnectedLocations = setConnectedLocations
@ -53,6 +56,7 @@ export default class InputPackets {
this.setScrollLog = setScrollLog this.setScrollLog = setScrollLog
this.logPresentationRef = logPresentationRef this.logPresentationRef = logPresentationRef
this.setMovingTo = setMovingTo this.setMovingTo = setMovingTo
this.setRemainingFrames = setRemainingFrames
} }
handle (packet: Packet): void { handle (packet: Packet): void {
@ -121,6 +125,9 @@ export default class InputPackets {
this.setMovingTo(null) this.setMovingTo(null)
} }
} }
if (data.remaining_frames !== undefined) {
this.setRemainingFrames(data.remaining_frames)
}
if (data.set_log !== undefined) { if (data.set_log !== undefined) {
saveScroll() saveScroll()
this.setLogLines(data.set_log) this.setLogLines(data.set_log)

View File

@ -129,6 +129,16 @@ sub _on_redis_event ( $self, $ws, $session, $message, $topic, $topics ) {
$info_packet_to_send->send($ws); $info_packet_to_send->send($ws);
return; return;
} }
if ($data->{command} eq 'show-frame') {
my $current_frame = $pj->team->action_frame;
if ($pj->team->is_moving) {
my $last_frame = $pj->team->location->parent->frames_to_move;
LasTres::Controller::Websocket::OutputPacket::Info->new(
remaining_frames => $last_frame - $current_frame
)->send($ws);
}
return;
}
} }
sub _get_connected_places ( $self, $pj ) { sub _get_connected_places ( $self, $pj ) {

View File

@ -22,16 +22,19 @@ has location_data => ( is => 'rw', );
has set_log => ( is => 'rw', ); has set_log => ( is => 'rw', );
has append_log => ( is => 'rw' ); has append_log => ( is => 'rw' );
has remaining_frames => ( is => 'rw' );
sub identifier { sub identifier {
return 'info'; return 'info';
} }
sub data ($self) { sub data ($self) {
my $clear = $self->clear; my $clear = $self->clear;
my $team_pjs = $self->team_pjs; my $team_pjs = $self->team_pjs;
my $location_data = $self->location_data; my $location_data = $self->location_data;
my $set_log = $self->set_log; my $set_log = $self->set_log;
my $append_log = $self->append_log; my $append_log = $self->append_log;
my $remaining_frames = $self->remaining_frames;
return { return {
( (
( defined $clear ) ? ( clear => $clear ) ( defined $clear ) ? ( clear => $clear )
@ -50,8 +53,12 @@ sub data ($self) {
: () : ()
), ),
( (
( defined $append_log ) ( defined $append_log ) ? ( append_log => $append_log )
? ( append_log => $append_log ) : ()
),
(
( defined $remaining_frames )
? ( remaining_frames => $remaining_frames )
: () : ()
) )
}; };

View File

@ -10,17 +10,11 @@ use feature 'signatures';
use Moo; use Moo;
use JSON qw/to_json from_json/; use JSON qw/to_json from_json/;
has _app => ( has _app => ( is => 'lazy' );
is => 'lazy'
);
has _schema => ( has _schema => ( is => 'lazy' );
is => 'lazy'
);
has _redis => ( has _redis => ( is => 'lazy' );
is => 'lazy'
);
sub _build__app { sub _build__app {
require LasTres; require LasTres;
@ -42,56 +36,59 @@ sub _exit_the_program {
} }
$SIG{CHLD} = 'IGNORE'; $SIG{CHLD} = 'IGNORE';
$SIG{INT} = \&_exit_the_program; $SIG{INT} = \&_exit_the_program;
$SIG{QUIT} = \&_exit_the_program; $SIG{QUIT} = \&_exit_the_program;
$SIG{TERM} = \&_exit_the_program; $SIG{TERM} = \&_exit_the_program;
sub loop($self) { sub loop ($self) {
my $child_pid = fork; my $child_pid = fork;
if (!$child_pid) { if ( !$child_pid ) {
$self->_real_loop; $self->_real_loop;
} }
} }
sub _work_frame($self) { sub _work_frame ($self) {
$self->_increment_frame_for_movers(); $self->_increment_frame_for_movers();
} }
sub _increment_frame_for_movers($self) { sub _increment_frame_for_movers ($self) {
my $schema = $self->_schema; my $schema = $self->_schema;
my $result_set_teams = $schema->resultset('Team'); my $result_set_teams = $schema->resultset('Team');
my @teams = $result_set_teams->search({-bool => 'is_moving'}); my @teams = $result_set_teams->search( { -bool => 'is_moving' } );
for my $team (@teams) { for my $team (@teams) {
$self->_increment_frame_for_mover($team); $self->_increment_frame_for_mover($team);
} }
} }
sub _increment_frame_for_mover($self, $team) { sub _increment_frame_for_mover ( $self, $team ) {
$team = $team->get_from_storage; $team = $team->get_from_storage;
my $frame = $team->action_frame; my $frame = $team->action_frame;
$team->action_frame(++$frame); $team->action_frame( ++$frame );
$team->update; $team->update;
my $location = $team->location; my $location = $team->location;
my $target_location = LasTres::Location::get(from_json($team->moving_to)->@*); my $target_location =
if ($frame >= $location->parent->frames_to_move) { LasTres::Location::get( from_json( $team->moving_to )->@* );
if ( $frame >= $location->parent->frames_to_move ) {
$team->action_frame(0); $team->action_frame(0);
$team->is_moving(0); $team->is_moving(0);
$team->moving_to('null'); $team->moving_to('null');
$team->update; $team->update;
$target_location->place_team($team); $target_location->place_team($team);
return;
} }
$team->send_frame_to_members;
} }
sub _real_loop($self) { sub _real_loop ($self) {
eval { eval {
my $redis = $self->_redis; my $redis = $self->_redis;
while (1) { while (1) {
if (!defined $redis->db->get($redis->executing_frame_key)) { if ( !defined $redis->db->get( $redis->executing_frame_key ) ) {
$redis->db->setex($redis->executing_frame_key, 10, 1); $redis->db->setex( $redis->executing_frame_key, 10, 1 );
$self->_work_frame; $self->_work_frame;
} }
my $ttl = $redis->db->ttl($redis->executing_frame_key); my $ttl = $redis->db->ttl( $redis->executing_frame_key );
if ($ttl > 0) { if ( $ttl > 0 ) {
sleep $ttl; sleep $ttl;
} }
} }

View File

@ -91,6 +91,7 @@ sub move ( $self, $team ) {
} }
my $schema; my $schema;
$team->is_moving(1); $team->is_moving(1);
$team->action_frame(0);
$team->moving_to( $self->to_json_array ); $team->moving_to( $self->to_json_array );
$team->update; $team->update;
$self->on_team_moving($team); $self->on_team_moving($team);
@ -102,6 +103,7 @@ sub on_team_moving ( $self, $team ) {
for my $pj ( $team->members ) { for my $pj ( $team->members ) {
$self->on_pj_moving($pj); $self->on_pj_moving($pj);
} }
$team->send_frame_to_members;
} }
sub on_pj_moving ( $self, $pj ) { sub on_pj_moving ( $self, $pj ) {

View File

@ -27,7 +27,7 @@ sub get_auto_discover($self) {
} }
sub frames_to_move { sub frames_to_move {
return 0; return 3;
} }
sub identifier { sub identifier {

View File

@ -8,90 +8,102 @@ use warnings;
use parent 'DBIx::Class::Core'; use parent 'DBIx::Class::Core';
use LasTres::Location; use LasTres::Location;
use JSON qw/to_json from_json/;
__PACKAGE__->table('teams'); __PACKAGE__->table('teams');
__PACKAGE__->add_columns( __PACKAGE__->add_columns(
uuid => { uuid => {
data_type => 'uuid', data_type => 'uuid',
is_nullable => 0, is_nullable => 0,
}, },
is_exploring => { is_exploring => {
data_type => 'boolean', data_type => 'boolean',
is_nullable => 0, is_nullable => 0,
default_value => \'false', default_value => \'false',
}, },
action_frame => { action_frame => {
data_type => 'integer', data_type => 'integer',
is_nullable => 0, is_nullable => 0,
default_value => \'0', default_value => \'0',
}, },
is_moving => { is_moving => {
data_type => 'boolean', data_type => 'boolean',
is_nullable => 0, is_nullable => 0,
default_value => \'false', default_value => \'false',
}, },
moving_to => { moving_to => {
data_type => 'jsonb', data_type => 'jsonb',
is_nullable => 0, is_nullable => 0,
default_value => \'\'null\'', default_value => \'\'null\'',
}, },
leader => { leader => {
data_type => 'uuid', data_type => 'uuid',
is_nullable => 1, is_nullable => 1,
is_foreign_key => 1, is_foreign_key => 1,
}, },
name => { name => {
data_type => 'text', data_type => 'text',
is_nullable => 0, is_nullable => 0,
}, },
planet => { planet => {
data_type => 'text', data_type => 'text',
is_nullable => 0, is_nullable => 0,
accessor => '_planet', accessor => '_planet',
}, },
super_area => { super_area => {
data_type => 'text', data_type => 'text',
is_nullable => 0, is_nullable => 0,
accessor => '_super_area', accessor => '_super_area',
}, },
area => { area => {
data_type => 'text', data_type => 'text',
is_nullable => 0, is_nullable => 0,
accessor => '_area', accessor => '_area',
}, },
location => { location => {
data_type => 'text', data_type => 'text',
is_nullable => 0, is_nullable => 0,
accessor => '_location', accessor => '_location',
}, },
); );
# May throw error, it is needed to handle. # May throw error, it is needed to handle.
sub location { sub location {
my $self = shift; my $self = shift;
my $location = shift; my $location = shift;
my $planet; my $planet;
my $super_area; my $super_area;
my $area; my $area;
if (defined $location) { if ( defined $location ) {
$self->_location($location->identifier); $self->_location( $location->identifier );
$area = $location->parent; $area = $location->parent;
$self->_area($area->identifier); $self->_area( $area->identifier );
$super_area = $area->parent; $super_area = $area->parent;
$self->_super_area($super_area->identifier); $self->_super_area( $super_area->identifier );
$planet = $super_area->parent; $planet = $super_area->parent;
$self->_planet($planet->identifier); $self->_planet( $planet->identifier );
} }
$location = $self->_location; $location = $self->_location;
$area = $self->_area; $area = $self->_area;
$super_area = $self->_super_area; $super_area = $self->_super_area;
$planet = $self->_planet; $planet = $self->_planet;
$location = LasTres::Location::get($planet, $super_area, $area, $location); $location =
LasTres::Location::get( $planet, $super_area, $area, $location );
return $location; return $location;
} }
sub send_frame_to_members ($self) {
require LasTres::Redis;
my $redis = LasTres::Redis->new;
$self = $self->get_from_storage;
for my $pj ( $self->members ) {
$redis->publish( $redis->pj_subscription($pj),
to_json( { command => 'show-frame' } ) );
}
}
__PACKAGE__->set_primary_key('uuid'); __PACKAGE__->set_primary_key('uuid');
__PACKAGE__->add_unique_constraint(u_name => ['name']); __PACKAGE__->add_unique_constraint( u_name => ['name'] );
__PACKAGE__->has_many('members', 'LasTres::Schema::Result::PJ', 'team'); __PACKAGE__->has_many( 'members', 'LasTres::Schema::Result::PJ', 'team' );
__PACKAGE__->belongs_to('leader', 'LasTres::Schema::Result::PJ'); __PACKAGE__->belongs_to( 'leader', 'LasTres::Schema::Result::PJ' );
1; 1;

File diff suppressed because one or more lines are too long