@@ -16,35 +16,39 @@ export enum ConnectionState {
16
16
// Note that we trust that server returns well-formed JSON. It would take far too much time to
17
17
// verify its adherence to the schema here, for little gain.
18
18
export class Connection {
19
+ private readonly link : link . ILink ;
20
+
19
21
private _state = ConnectionState . Initializing ;
20
22
21
23
private _commands : string [ ] = [ ] ;
22
24
private _events : string [ ] = [ ] ;
23
25
private _itemValuesEncodings : string [ ] = [ ] ;
24
26
25
27
private promises : {
26
- resolve : ( response : proto . AnyResponse ) => void ;
28
+ resolve : ( response : link . Packet < proto . AnyResponse > ) => void ;
27
29
reject : ( error : Error ) => void ;
28
30
} [ ] = [ ] ;
29
31
private timestamps : Date [ ] = [ ] ;
30
32
31
33
private sendIndex : number = 0 ;
32
34
private recvIndex : number = 0 ;
33
35
34
- constructor ( private readonly link : link . ILink ) {
36
+ constructor ( link_ : link . ILink ) {
37
+ this . link = link_ ;
35
38
this . link . onRecv = this . onLinkRecv . bind ( this ) ;
36
39
this . link . onDone = this . onLinkDone . bind ( this ) ;
37
- this . send ( {
40
+ this . send ( link . Packet . fromObject ( {
38
41
type : 'greeting' ,
39
42
version : 0 ,
40
- } ) ;
43
+ } ) ) ;
41
44
}
42
45
43
46
dispose ( ) : void {
44
47
this . link . dispose ( ) ;
45
48
}
46
49
47
- private traceSend ( packet : proto . ClientPacket ) {
50
+ private traceSend ( linkPacket : link . Packet < proto . ClientPacket > ) {
51
+ const packet = linkPacket . asObject ( ) ;
48
52
if ( packet . type === 'greeting' ) {
49
53
console . debug ( '[CXXRTL] C>S' , packet ) ;
50
54
} else if ( packet . type === 'command' ) {
@@ -53,7 +57,8 @@ export class Connection {
53
57
}
54
58
}
55
59
56
- private traceRecv ( packet : proto . ServerPacket ) {
60
+ private traceRecv ( linkPacket : link . Packet < proto . ServerPacket > ) {
61
+ const packet = linkPacket . asObject ( ) ;
57
62
if ( packet . type === 'greeting' ) {
58
63
console . debug ( '[CXXRTL] S>C' , packet ) ;
59
64
} else if ( packet . type === 'response' ) {
@@ -67,17 +72,18 @@ export class Connection {
67
72
}
68
73
}
69
74
70
- private async send ( packet : proto . ClientPacket ) : Promise < void > {
71
- this . traceSend ( packet ) ;
75
+ private async send ( linkPacket : link . Packet < proto . ClientPacket > ) : Promise < void > {
76
+ this . traceSend ( linkPacket ) ;
72
77
if ( this . _state === ConnectionState . Disconnected ) {
73
78
throw new Error ( 'unable to send packet after link is shutdown' ) ;
74
79
} else {
75
- this . link . send ( packet ) ;
80
+ this . link . send ( linkPacket ) ;
76
81
}
77
82
}
78
83
79
- private async onLinkRecv ( packet : proto . ServerPacket ) : Promise < void > {
80
- this . traceRecv ( packet ) ;
84
+ private async onLinkRecv ( linkPacket : link . Packet < proto . ServerPacket > ) : Promise < void > {
85
+ this . traceRecv ( linkPacket ) ;
86
+ const packet = linkPacket . asObject ( ) ;
81
87
if ( this . _state === ConnectionState . Initializing && packet . type === 'greeting' ) {
82
88
if ( packet . version === 0 ) {
83
89
this . _commands = packet . commands ;
@@ -93,15 +99,15 @@ export class Connection {
93
99
const nextPromise = this . promises . shift ( ) ;
94
100
if ( nextPromise !== undefined ) {
95
101
if ( packet . type === 'response' ) {
96
- nextPromise . resolve ( packet ) ;
102
+ nextPromise . resolve ( link . Packet . fromObject ( packet ) ) ;
97
103
} else {
98
104
nextPromise . reject ( new CommandError ( packet ) ) ;
99
105
}
100
106
} else {
101
107
this . rejectPromises ( new Error ( `unexpected '${ packet . type } ' reply with no commands queued` ) ) ;
102
108
}
103
109
} else if ( this . _state === ConnectionState . Connected && packet . type === 'event' ) {
104
- await this . onEvent ( packet ) ;
110
+ await this . onEvent ( link . Packet . fromObject ( packet ) ) ;
105
111
} else {
106
112
this . rejectPromises ( new Error ( `unexpected ${ packet . type } packet received for ${ this . _state } connection` ) ) ;
107
113
}
@@ -119,7 +125,7 @@ export class Connection {
119
125
}
120
126
}
121
127
122
- async perform ( command : proto . AnyCommand ) : Promise < proto . AnyResponse > {
128
+ async exchange ( command : link . Packet < proto . AnyCommand > ) : Promise < link . Packet < proto . AnyResponse > > {
123
129
await this . send ( command ) ;
124
130
return new Promise ( ( resolve , reject ) => {
125
131
this . promises . push ( { resolve, reject } ) ;
@@ -130,7 +136,7 @@ export class Connection {
130
136
131
137
async onDisconnected ( ) : Promise < void > { }
132
138
133
- async onEvent ( _event : proto . AnyEvent ) : Promise < void > { }
139
+ async onEvent ( _event : link . Packet < proto . AnyEvent > ) : Promise < void > { }
134
140
135
141
get state ( ) : ConnectionState {
136
142
return this . _state ;
@@ -148,31 +154,36 @@ export class Connection {
148
154
return this . _itemValuesEncodings . slice ( ) ;
149
155
}
150
156
157
+ private async command < T extends proto . AnyResponse > ( command : proto . AnyCommand ) : Promise < T > {
158
+ const response = await this . exchange ( link . Packet . fromObject ( command ) ) ;
159
+ return response . cast < T > ( ) . asObject ( ) ;
160
+ }
161
+
151
162
async listScopes ( command : proto . CommandListScopes ) : Promise < proto . ResponseListScopes > {
152
- return await this . perform ( command ) as proto . ResponseListScopes ;
163
+ return this . command < proto . ResponseListScopes > ( command ) ;
153
164
}
154
165
155
166
async listItems ( command : proto . CommandListItems ) : Promise < proto . ResponseListItems > {
156
- return await this . perform ( command ) as proto . ResponseListItems ;
167
+ return this . command < proto . ResponseListItems > ( command ) ;
157
168
}
158
169
159
170
async referenceItems ( command : proto . CommandReferenceItems ) : Promise < proto . ResponseReferenceItems > {
160
- return await this . perform ( command ) as proto . ResponseReferenceItems ;
171
+ return this . command < proto . ResponseReferenceItems > ( command ) ;
161
172
}
162
173
163
174
async queryInterval ( command : proto . CommandQueryInterval ) : Promise < proto . ResponseQueryInterval > {
164
- return await this . perform ( command ) as proto . ResponseQueryInterval ;
175
+ return this . command < proto . ResponseQueryInterval > ( command ) ;
165
176
}
166
177
167
178
async getSimulationStatus ( command : proto . CommandGetSimulationStatus ) : Promise < proto . ResponseGetSimulationStatus > {
168
- return await this . perform ( command ) as proto . ResponseGetSimulationStatus ;
179
+ return this . command < proto . ResponseGetSimulationStatus > ( command ) ;
169
180
}
170
181
171
182
async runSimulation ( command : proto . CommandRunSimulation ) : Promise < proto . ResponseRunSimulation > {
172
- return await this . perform ( command ) as proto . ResponseRunSimulation ;
183
+ return this . command < proto . ResponseRunSimulation > ( command ) ;
173
184
}
174
185
175
186
async pauseSimulation ( command : proto . CommandPauseSimulation ) : Promise < proto . ResponsePauseSimulation > {
176
- return await this . perform ( command ) as proto . ResponsePauseSimulation ;
187
+ return this . command < proto . ResponsePauseSimulation > ( command ) ;
177
188
}
178
189
}
0 commit comments