@@ -9,11 +9,18 @@ import { sendPacket } from "../packet";
99import { Ticker } from "pixi.js" ;
1010import { DeviceId } from "../graphs/datagraph" ;
1111import { Layer } from "./layer" ;
12+ import { isHost , RunningProgram } from "../graphs/datagraph" ;
1213
1314const DEFAULT_ECHO_DELAY = 250 ; // ms
1415
16+ const ECHO_SERVER_NAME = "Echo server" ;
17+
18+ type ProgramTicker = ( ticker : Ticker ) => void ;
19+ type Pid = number ;
20+
1521export class Host extends Device {
16- currentProgram : ( ticker : Ticker ) => void = undefined ;
22+ private runningPrograms = new Map < Pid , ProgramTicker > ( ) ;
23+ private programId = 0 ;
1724
1825 constructor (
1926 id : DeviceId ,
@@ -23,6 +30,7 @@ export class Host extends Device {
2330 mask : IpAddress ,
2431 ) {
2532 super ( id , PcImage , viewgraph , position , ip , mask ) ;
33+ this . loadRunningPrograms ( ) ;
2634 }
2735
2836 showInfo ( ) : void {
@@ -53,30 +61,58 @@ export class Host extends Device {
5361 ) ;
5462 const destination = dropdownContainer . querySelector ( "select" ) ;
5563
64+ // TODO: extract into classes
5665 const programList : ProgramInfo [ ] = [
57- { name : "No program" , start : ( ) => this . stopProgram ( ) } ,
5866 {
5967 name : "Send ICMP echo" ,
6068 inputs : [ dropdownContainer ] ,
6169 start : ( ) => this . sendSingleEcho ( destination . value ) ,
6270 } ,
6371 {
64- name : "Echo server" ,
72+ name : ECHO_SERVER_NAME ,
6573 inputs : [ dropdownContainer ] ,
66- start : ( ) => this . startEchoServer ( destination . value ) ,
74+ start : ( ) => this . startNewEchoServer ( destination . value ) ,
6775 } ,
6876 ] ;
6977 return programList ;
7078 }
7179
72- sendSingleEcho ( id : string ) {
73- this . stopProgram ( ) ;
80+ private addRunningProgram ( program : RunningProgram ) {
81+ this . viewgraph . getDataGraph ( ) . modifyDevice ( this . id , ( device ) => {
82+ if ( ! isHost ( device ) ) {
83+ console . error ( "Node is not a Host" ) ;
84+ return ;
85+ }
86+ device . runningPrograms . push ( program ) ;
87+ } ) ;
88+ }
89+
90+ private loadRunningPrograms ( ) {
91+ const device = this . viewgraph . getDataGraph ( ) . getDevice ( this . id ) ;
92+ if ( ! isHost ( device ) ) {
93+ console . error ( "Node is not a Host" ) ;
94+ return ;
95+ }
96+ device . runningPrograms . forEach ( ( program ) => {
97+ if ( program . name !== ECHO_SERVER_NAME ) {
98+ console . error ( "Unknown program: " , program . name ) ;
99+ return ;
100+ }
101+ this . startEchoServer ( program . inputs [ 0 ] ) ;
102+ } ) ;
103+ }
104+
105+ private sendSingleEcho ( id : string ) {
74106 const dst = parseInt ( id ) ;
75107 sendPacket ( this . viewgraph , "ICMP" , this . id , dst ) ;
76108 }
77109
78- startEchoServer ( id : string ) {
79- this . stopProgram ( ) ;
110+ private startNewEchoServer ( id : string ) {
111+ this . addRunningProgram ( { name : "Echo server" , inputs : [ id ] } ) ;
112+ this . startEchoServer ( id ) ;
113+ }
114+
115+ private startEchoServer ( id : string ) {
80116 const dst = parseInt ( id ) ;
81117 let progress = 0 ;
82118 const send = ( ticker : Ticker ) => {
@@ -88,13 +124,29 @@ export class Host extends Device {
88124 sendPacket ( this . viewgraph , "ICMP" , this . id , dst ) ;
89125 progress -= delay ;
90126 } ;
91- Ticker . shared . add ( send , this ) ;
92- this . currentProgram = send ;
127+ this . startProgram ( send ) ;
93128 }
94129
95- stopProgram ( ) {
96- if ( this . currentProgram ) {
97- Ticker . shared . remove ( this . currentProgram , this ) ;
130+ private startProgram ( tick : ( ticker : Ticker ) => void ) : Pid {
131+ const pid = ++ this . programId ;
132+ this . runningPrograms . set ( pid , tick ) ;
133+ Ticker . shared . add ( tick , this ) ;
134+ return pid ;
135+ }
136+
137+ // TODO: this is unused
138+ stopProgram ( pid : Pid ) {
139+ const tick = this . runningPrograms . get ( pid ) ;
140+ if ( ! tick ) {
141+ console . error ( "Pid not found: " , pid ) ;
142+ return ;
98143 }
144+ Ticker . shared . remove ( tick , this ) ;
145+ this . runningPrograms . delete ( pid ) ;
146+ }
147+
148+ destroy ( ) {
149+ this . runningPrograms . forEach ( ( tick ) => Ticker . shared . remove ( tick , this ) ) ;
150+ this . runningPrograms . clear ( ) ;
99151 }
100152}
0 commit comments