brotorift 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/brotorift +12 -0
- data/lib/ast.rb +169 -0
- data/lib/brotorift.rb +102 -0
- data/lib/case_helper.rb +13 -0
- data/lib/compiler.rb +288 -0
- data/lib/compiler_error.rb +191 -0
- data/lib/generators/elixir_server_generator.ex.erb +162 -0
- data/lib/generators/elixir_server_generator.rb +435 -0
- data/lib/generators/scala_server_generator.rb +137 -0
- data/lib/generators/scala_server_generator.scala.erb +92 -0
- data/lib/generators/unity_client_generator.cs.erb +103 -0
- data/lib/generators/unity_client_generator.rb +188 -0
- data/lib/lexer.rb +42 -0
- data/lib/parser.rb +105 -0
- data/lib/runtime.rb +345 -0
- data/lib/sequence_diagram_generator.rb +47 -0
- metadata +88 -0
@@ -0,0 +1,435 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require_relative '../case_helper'
|
3
|
+
|
4
|
+
class EnumTypeDef
|
5
|
+
def elixir_name
|
6
|
+
@name.underscore
|
7
|
+
end
|
8
|
+
|
9
|
+
def elixir_read_name
|
10
|
+
"read_#{self.elixir_name}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def elixir_write_name
|
14
|
+
"write_#{self.elixir_name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def elixir_read
|
18
|
+
"#{self.elixir_read_name}(data)"
|
19
|
+
end
|
20
|
+
|
21
|
+
def elixir_write member_name
|
22
|
+
"#{self.elixir_write_name}(data, #{member_name})"
|
23
|
+
end
|
24
|
+
|
25
|
+
def elixir_reader
|
26
|
+
"#{self.elixir_read_name}/1"
|
27
|
+
end
|
28
|
+
|
29
|
+
def elixir_writer
|
30
|
+
"#{self.elixir_write_name}/2"
|
31
|
+
end
|
32
|
+
|
33
|
+
def elixir_type
|
34
|
+
@elements.values.map { |e| e.elixir_name } .join ' | '
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
class EnumElementDef
|
40
|
+
def elixir_name
|
41
|
+
':' + @name.underscore
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
class BuiltinTypeDef
|
47
|
+
def elixir_type
|
48
|
+
case @name
|
49
|
+
when 'Bool'
|
50
|
+
return 'boolean()'
|
51
|
+
when 'Byte'
|
52
|
+
return 'byte()'
|
53
|
+
when 'Short'
|
54
|
+
return 'integer()'
|
55
|
+
when 'Int'
|
56
|
+
return 'integer()'
|
57
|
+
when 'Long'
|
58
|
+
return 'integer()'
|
59
|
+
when 'UShort'
|
60
|
+
return 'non_neg_integer()'
|
61
|
+
when 'UInt'
|
62
|
+
return 'non_neg_integer()'
|
63
|
+
when 'ULong'
|
64
|
+
return 'non_neg_integer()'
|
65
|
+
when 'Float'
|
66
|
+
return 'float()'
|
67
|
+
when 'Double'
|
68
|
+
return 'float()'
|
69
|
+
when 'String'
|
70
|
+
return 'String.t()'
|
71
|
+
when 'DateTime'
|
72
|
+
return 'DateTime.t()'
|
73
|
+
when 'ByteBuffer'
|
74
|
+
return 'binary()'
|
75
|
+
when 'Vector2'
|
76
|
+
return '{float(), float()}'
|
77
|
+
when 'Vector3'
|
78
|
+
return '{float(), float(), float()}'
|
79
|
+
when 'Color'
|
80
|
+
return '{float(), float(), float(), float()}'
|
81
|
+
else
|
82
|
+
return @name
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def elixir_read
|
87
|
+
case @name
|
88
|
+
when 'Bool'
|
89
|
+
return "Brotorift.Binary.read_bool(data)"
|
90
|
+
when 'Byte'
|
91
|
+
return "Brotorift.Binary.read_byte(data)"
|
92
|
+
when 'Short'
|
93
|
+
return "Brotorift.Binary.read_short(data)"
|
94
|
+
when 'Int'
|
95
|
+
return "Brotorift.Binary.read_int(data)"
|
96
|
+
when 'Long'
|
97
|
+
return "Brotorift.Binary.read_long(data)"
|
98
|
+
when 'UShort'
|
99
|
+
return "Brotorift.Binary.read_ushort(data)"
|
100
|
+
when 'UInt'
|
101
|
+
return "Brotorift.Binary.read_uint(data)"
|
102
|
+
when 'ULong'
|
103
|
+
return "Brotorift.Binary.read_ulong(data)"
|
104
|
+
when 'Float'
|
105
|
+
return "Brotorift.Binary.read_float(data)"
|
106
|
+
when 'Double'
|
107
|
+
return "Brotorift.Binary.read_double(data)"
|
108
|
+
when 'String'
|
109
|
+
return "Brotorift.Binary.read_string(data)"
|
110
|
+
when 'ByteBuffer'
|
111
|
+
return "Brotorift.Binary.read_byte_buffer(data)"
|
112
|
+
when 'Vector2'
|
113
|
+
return "Brotorift.Binary.read_vector2(data)"
|
114
|
+
when 'Vector3'
|
115
|
+
return "Brotorift.Binary.read_vector3(data)"
|
116
|
+
when 'Color'
|
117
|
+
return "Brotorift.Binary.read_color(data)"
|
118
|
+
else
|
119
|
+
throw 'Invalid operation'
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def elixir_write member_name
|
124
|
+
case @name
|
125
|
+
when 'Bool'
|
126
|
+
return "Brotorift.Binary.write_bool(data, #{member_name})"
|
127
|
+
when 'Byte'
|
128
|
+
return "Brotorift.Binary.write_byte(data, #{member_name})"
|
129
|
+
when 'Short'
|
130
|
+
return "Brotorift.Binary.write_short(data, #{member_name})"
|
131
|
+
when 'Int'
|
132
|
+
return "Brotorift.Binary.write_int(data, #{member_name})"
|
133
|
+
when 'Long'
|
134
|
+
return "Brotorift.Binary.write_long(data, #{member_name})"
|
135
|
+
when 'UShort'
|
136
|
+
return "Brotorift.Binary.write_ushort(data, #{member_name})"
|
137
|
+
when 'UInt'
|
138
|
+
return "Brotorift.Binary.write_uint(data, #{member_name})"
|
139
|
+
when 'ULong'
|
140
|
+
return "Brotorift.Binary.write_ulong(data, #{member_name})"
|
141
|
+
when 'Float'
|
142
|
+
return "Brotorift.Binary.write_float(data, #{member_name})"
|
143
|
+
when 'Double'
|
144
|
+
return "Brotorift.Binary.write_double(data, #{member_name})"
|
145
|
+
when 'String'
|
146
|
+
return "Brotorift.Binary.write_string(data, #{member_name})"
|
147
|
+
when 'ByteBuffer'
|
148
|
+
return "Brotorift.Binary.write_byte_buffer(data, #{member_name})"
|
149
|
+
when 'Vector2'
|
150
|
+
return "Brotorift.Binary.write_vector2(data, #{member_name})"
|
151
|
+
when 'Vector3'
|
152
|
+
return "Brotorift.Binary.write_vector3(data, #{member_name})"
|
153
|
+
when 'Color'
|
154
|
+
return "Brotorift.Binary.write_color(data, #{member_name})"
|
155
|
+
else
|
156
|
+
throw 'Invalid operation'
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def elixir_reader
|
161
|
+
case @name
|
162
|
+
when 'Bool'
|
163
|
+
return "&Brotorift.Binary.read_bool/1"
|
164
|
+
when 'Byte'
|
165
|
+
return "&Brotorift.Binary.read_byte/1"
|
166
|
+
when 'Short'
|
167
|
+
return "&Brotorift.Binary.read_short/1"
|
168
|
+
when 'Int'
|
169
|
+
return "&Brotorift.Binary.read_int/1"
|
170
|
+
when 'Long'
|
171
|
+
return "&Brotorift.Binary.read_long/1"
|
172
|
+
when 'UShort'
|
173
|
+
return "&Brotorift.Binary.read_ushort/1"
|
174
|
+
when 'UInt'
|
175
|
+
return "&Brotorift.Binary.read_uint/1"
|
176
|
+
when 'ULong'
|
177
|
+
return "&Brotorift.Binary.read_ulong/1"
|
178
|
+
when 'Float'
|
179
|
+
return "&Brotorift.Binary.read_float/1"
|
180
|
+
when 'Double'
|
181
|
+
return "&Brotorift.Binary.read_double/1"
|
182
|
+
when 'String'
|
183
|
+
return "&Brotorift.Binary.read_string/1"
|
184
|
+
when 'ByteBuffer'
|
185
|
+
return "&Brotorift.Binary.read_byte_buffer/1"
|
186
|
+
when 'Vector2'
|
187
|
+
return "&Brotorift.Binary.read_vector2/1"
|
188
|
+
when 'Vector3'
|
189
|
+
return "&Brotorift.Binary.read_vector3/1"
|
190
|
+
when 'Color'
|
191
|
+
return "&Brotorift.Binary.read_color/1"
|
192
|
+
else
|
193
|
+
throw 'Invalid operation'
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def elixir_writer
|
198
|
+
case @name
|
199
|
+
when 'Bool'
|
200
|
+
return "&Brotorift.Binary.write_bool/2"
|
201
|
+
when 'Byte'
|
202
|
+
return "&Brotorift.Binary.write_byte/2"
|
203
|
+
when 'Short'
|
204
|
+
return "&Brotorift.Binary.write_short/2"
|
205
|
+
when 'Int'
|
206
|
+
return "&Brotorift.Binary.write_int/2"
|
207
|
+
when 'Long'
|
208
|
+
return "&Brotorift.Binary.write_long/2"
|
209
|
+
when 'UShort'
|
210
|
+
return "&Brotorift.Binary.write_ushort/2"
|
211
|
+
when 'UInt'
|
212
|
+
return "&Brotorift.Binary.write_uint/2"
|
213
|
+
when 'ULong'
|
214
|
+
return "&Brotorift.Binary.write_ulong/2"
|
215
|
+
when 'Float'
|
216
|
+
return "&Brotorift.Binary.write_float/2"
|
217
|
+
when 'Double'
|
218
|
+
return "&Brotorift.Binary.write_double/2"
|
219
|
+
when 'String'
|
220
|
+
return "&Brotorift.Binary.write_string/2"
|
221
|
+
when 'ByteBuffer'
|
222
|
+
return "&Brotorift.Binary.write_byte_buffer/2"
|
223
|
+
when 'Vector2'
|
224
|
+
return "&Brotorift.Binary.write_vector2/2"
|
225
|
+
when 'Vector3'
|
226
|
+
return "&Brotorift.Binary.write_vector3/2"
|
227
|
+
when 'Color'
|
228
|
+
return "&Brotorift.Binary.write_color/2"
|
229
|
+
else
|
230
|
+
throw 'Invalid operation'
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
class StructTypeDef
|
237
|
+
def elixir_members
|
238
|
+
@members.map { |m| ":" + m.elixir_name } .join ', '
|
239
|
+
end
|
240
|
+
|
241
|
+
def elixir_members_with_types node
|
242
|
+
@members.map { |m| m.elixir_name + ": " + m.type.elixir_type(node) } .join ', '
|
243
|
+
end
|
244
|
+
|
245
|
+
def elixir_members_with_values
|
246
|
+
@members.map { |m| m.elixir_name + ": " + m.elixir_name } .join ', '
|
247
|
+
end
|
248
|
+
|
249
|
+
def elixir_type node
|
250
|
+
"#{node.namespace}.#{@name}.t"
|
251
|
+
end
|
252
|
+
|
253
|
+
def elixir_read node
|
254
|
+
"#{node.namespace}.#{@name}.read(data)"
|
255
|
+
end
|
256
|
+
|
257
|
+
def elixir_write node, member_name
|
258
|
+
"#{node.namespace}.#{@name}.write(data, #{member_name})"
|
259
|
+
end
|
260
|
+
|
261
|
+
def elixir_reader node
|
262
|
+
"#{node.namespace}.#{@name}.read/1"
|
263
|
+
end
|
264
|
+
|
265
|
+
def elixir_writer node
|
266
|
+
"#{node.namespace}.#{@name}.write/2"
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
|
271
|
+
class TypeInstanceDef
|
272
|
+
def elixir_type node
|
273
|
+
return self.elixir_list node if @type.name == 'List'
|
274
|
+
return self.elixir_set node if @type.name == 'Set'
|
275
|
+
return self.elixir_map node if @type.name == 'Map'
|
276
|
+
return @type.elixir_type if @type.is_a? BuiltinTypeDef or @type.is_a? EnumTypeDef
|
277
|
+
return @type.elixir_type node if @type.is_a? StructTypeDef
|
278
|
+
end
|
279
|
+
|
280
|
+
def elixir_read node
|
281
|
+
return self.elixir_list_read node if @type.name == 'List'
|
282
|
+
return self.elixir_set_read node if @type.name == 'Set'
|
283
|
+
return self.elixir_map_read node if @type.name == 'Map'
|
284
|
+
return @type.elixir_read if @type.is_a? BuiltinTypeDef or @type.is_a? EnumTypeDef
|
285
|
+
return @type.elixir_read node if @type.is_a? StructTypeDef
|
286
|
+
end
|
287
|
+
|
288
|
+
def elixir_write node, member_name
|
289
|
+
return self.elixir_list_write node, member_name if @type.name == 'List'
|
290
|
+
return self.elixir_set_write node, member_name if @type.name == 'Set'
|
291
|
+
return self.elixir_map_write node, member_name if @type.name == 'Map'
|
292
|
+
return @type.elixir_write member_name if @type.is_a? BuiltinTypeDef or @type.is_a? EnumTypeDef
|
293
|
+
return @type.elixir_write node, member_name if @type.is_a? StructTypeDef
|
294
|
+
end
|
295
|
+
|
296
|
+
def elixir_reader node
|
297
|
+
return self.elixir_list_reader node if @type.name == 'List'
|
298
|
+
return self.elixir_set_reader node if @type.name == 'Set'
|
299
|
+
return self.elixir_map_reader node if @type.name == 'Map'
|
300
|
+
return @type.elixir_reader if @type.is_a? BuiltinTypeDef or @type.is_a? EnumTypeDef
|
301
|
+
return @type.elixir_reader node if @type.is_a? StructTypeDef
|
302
|
+
end
|
303
|
+
|
304
|
+
def elixir_writer node
|
305
|
+
return self.elixir_list_writer node if @type.name == 'List'
|
306
|
+
return self.elixir_set_writer node if @type.name == 'Set'
|
307
|
+
return self.elixir_map_writer node if @type.name == 'Map'
|
308
|
+
return @type.elixir_writer if @type.is_a? BuiltinTypeDef or @type.is_a? EnumTypeDef
|
309
|
+
return @type.elixir_writer node if @type.is_a? StructTypeDef
|
310
|
+
end
|
311
|
+
|
312
|
+
def elixir_list node
|
313
|
+
'list(' + @params[0].elixir_type(node) + ')'
|
314
|
+
end
|
315
|
+
|
316
|
+
def elixir_list_read node
|
317
|
+
'read_list(data, ' + @params[0].elixir_reader(node) + ')'
|
318
|
+
end
|
319
|
+
|
320
|
+
def elixir_list_write node, member_name
|
321
|
+
'write_list(data, ' + member_name + ', ' + @params[0].elixir_writer(node) + ')'
|
322
|
+
end
|
323
|
+
|
324
|
+
def elixir_list_reader node
|
325
|
+
'&Brotorift.Binary.read_list(&1, ' + @params[0].elixir_reader(node) + ')'
|
326
|
+
end
|
327
|
+
|
328
|
+
def elixir_list_writer node
|
329
|
+
'&Brotorift.Binary.write_list(&1, &2, ' + @params[0].elixir_writer(node) + ')'
|
330
|
+
end
|
331
|
+
|
332
|
+
def elixir_set node
|
333
|
+
'MapSet.t(' + @params[0].elixir_type(node) + ')'
|
334
|
+
end
|
335
|
+
|
336
|
+
def elixir_set_read node
|
337
|
+
'read_set(data, ' + @params[0].elixir_reader(node) + ')'
|
338
|
+
end
|
339
|
+
|
340
|
+
def elixir_set_write node, member_name
|
341
|
+
'write_set(data, ' + member_name + ', ' + @params[0].elixir_writer(node) + ')'
|
342
|
+
end
|
343
|
+
|
344
|
+
def elixir_set_reader node
|
345
|
+
'&Brotorift.Binary.read_set(&1, ' + @params[0].elixir_reader(node) + ')'
|
346
|
+
end
|
347
|
+
|
348
|
+
def elixir_set_writer node
|
349
|
+
'&Brotorift.Binary.write_set(&1, &2, ' + @params[0].elixir_writer(node) + ')'
|
350
|
+
end
|
351
|
+
|
352
|
+
def elixir_map node
|
353
|
+
'%{' + @params[0].elixir_type(node) + ' => ' + @params[1].elixir_type(node) + '}'
|
354
|
+
end
|
355
|
+
|
356
|
+
def elixir_map_read node
|
357
|
+
'read_map(data, ' + @params[0].elixir_reader(node) + ', ' + @params[1].elixir_reader(node) + ')'
|
358
|
+
end
|
359
|
+
|
360
|
+
def elixir_map_write node, member_name
|
361
|
+
'write_map(data, ' + member_name + ', ' + @params[0].elixir_writer(node) + ', ' + @params[1].elixir_writer(node) + ')'
|
362
|
+
end
|
363
|
+
|
364
|
+
def elixir_map_reader node
|
365
|
+
'&Brotorift.Binary.read_map(&1, ' + @params[0].elixir_reader(node) + ', ' + @params[1].elixir_reader(node) + ')'
|
366
|
+
end
|
367
|
+
|
368
|
+
def elixir_map_writer node
|
369
|
+
'&Brotorift.Binary.write_map(&1, &2, ' + @params[0].elixir_writer(node) + ', ' + @params[1].elixir_writer(node) + ')'
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
|
374
|
+
class MemberDef
|
375
|
+
def elixir_name
|
376
|
+
@name.underscore
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
|
381
|
+
class MessageDef
|
382
|
+
def elixir_header_name
|
383
|
+
"@header_#{self.elixir_name}"
|
384
|
+
end
|
385
|
+
|
386
|
+
def elixir_name
|
387
|
+
@name.underscore
|
388
|
+
end
|
389
|
+
|
390
|
+
def elixir_params
|
391
|
+
return '' if members.empty?
|
392
|
+
params = members.map { |m| m.elixir_name } .join ', '
|
393
|
+
', ' + params
|
394
|
+
end
|
395
|
+
|
396
|
+
def elixir_params_with_types node
|
397
|
+
return '' if members.empty?
|
398
|
+
params = members.map { |m| m.elixir_name + ' :: ' + m.type.elixir_type(node) } .join ', '
|
399
|
+
', ' + params
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
|
404
|
+
class NodeDef
|
405
|
+
def elixir_name
|
406
|
+
@name.underscore
|
407
|
+
end
|
408
|
+
|
409
|
+
def elixir_connection
|
410
|
+
@name + 'Connection'
|
411
|
+
end
|
412
|
+
|
413
|
+
def elixir_behaviour
|
414
|
+
@name + 'Behaviour'
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
|
419
|
+
class ElixirServerGenerator < Generator
|
420
|
+
def initialize
|
421
|
+
super 'elixir', :server
|
422
|
+
end
|
423
|
+
|
424
|
+
def generate node, runtime
|
425
|
+
folder = File.expand_path File.dirname __FILE__
|
426
|
+
erb_file = folder + '/elixir_server_generator.ex.erb'
|
427
|
+
template = File.read erb_file
|
428
|
+
erb = ERB.new template
|
429
|
+
content = erb.result binding
|
430
|
+
File.write "#{node.elixir_name}.ex", content
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
|
435
|
+
Generator.add ElixirServerGenerator.new
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require_relative '../case_helper'
|
3
|
+
|
4
|
+
|
5
|
+
class BuiltinTypeDef
|
6
|
+
def scala
|
7
|
+
case @name
|
8
|
+
when 'Bool'
|
9
|
+
return 'Boolean'
|
10
|
+
when 'ByteBuffer'
|
11
|
+
return 'ByteString'
|
12
|
+
else
|
13
|
+
return @name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
class EnumTypeDef
|
20
|
+
def scala
|
21
|
+
@name + '.Value'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
class StructTypeDef
|
27
|
+
def scala
|
28
|
+
@name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
class TypeInstanceDef
|
34
|
+
def scala
|
35
|
+
"#{@type.scala}#{scala_type_param}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def scala_type_param
|
39
|
+
return '' if @params.empty?
|
40
|
+
param_str = @params.map { |p| p.scala } .join ', '
|
41
|
+
'[' + param_str + ']'
|
42
|
+
end
|
43
|
+
|
44
|
+
def scala_read is_top_scope
|
45
|
+
str = ''
|
46
|
+
if @type.is_a? StructTypeDef
|
47
|
+
str = "packet.readStruct(new #{@type.name})"
|
48
|
+
elsif @type.is_a? EnumTypeDef
|
49
|
+
str = "#{@type.name}(packet.readInt())"
|
50
|
+
else
|
51
|
+
str = "packet.read#{scala_type}"
|
52
|
+
if @params.empty?
|
53
|
+
str += '()'
|
54
|
+
else
|
55
|
+
param_str = @params.map { |p| p.scala_read false } .join ', '
|
56
|
+
str += '(' + param_str + ')'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
unless is_top_scope
|
61
|
+
str = '() => ' + str
|
62
|
+
end
|
63
|
+
|
64
|
+
str
|
65
|
+
end
|
66
|
+
|
67
|
+
def scala_write member_name, is_top_scope
|
68
|
+
str = ''
|
69
|
+
if @type.is_a? StructTypeDef
|
70
|
+
str = "packet.writeStruct(#{member_name})"
|
71
|
+
elsif @type.is_a? EnumTypeDef
|
72
|
+
str = "packet.writeInt(#{member_name}.id)"
|
73
|
+
else
|
74
|
+
str = "packet.write#{scala_type}"
|
75
|
+
if @params.empty?
|
76
|
+
str += "(#{member_name})"
|
77
|
+
else
|
78
|
+
param_str = @params.map { |p| p.scala_write '_', false } .join ', '
|
79
|
+
str += "(#{member_name}, #{param_str})"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
str
|
84
|
+
end
|
85
|
+
|
86
|
+
def scala_type
|
87
|
+
@type.name + scala_type_param
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
class MemberDef
|
93
|
+
def scala_read
|
94
|
+
@type.scala_read true
|
95
|
+
end
|
96
|
+
|
97
|
+
def scala_write
|
98
|
+
@type.scala_write @name, true
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
class MessageDef
|
104
|
+
def scala_method
|
105
|
+
@name.decapitalize
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
class NodeDirection
|
111
|
+
def service_name
|
112
|
+
"#{@remote.name}Service"
|
113
|
+
end
|
114
|
+
|
115
|
+
def connection_name
|
116
|
+
"#{@remote.name}ConnectionBase"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
class ScalaServerGenerator < Generator
|
122
|
+
def initialize
|
123
|
+
super 'scala', :server
|
124
|
+
end
|
125
|
+
|
126
|
+
def generate node, runtime
|
127
|
+
folder = File.expand_path File.dirname __FILE__
|
128
|
+
erb_file = folder + '/scala_server_generator.scala.erb'
|
129
|
+
template = File.read erb_file
|
130
|
+
erb = ERB.new template
|
131
|
+
content = erb.result binding
|
132
|
+
File.write "#{node.name}.scala", content
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
Generator.add ScalaServerGenerator.new
|
@@ -0,0 +1,92 @@
|
|
1
|
+
package <%= node.namespace %>
|
2
|
+
|
3
|
+
import brotorift._
|
4
|
+
import java.net.InetSocketAddress
|
5
|
+
import akka.actor.Props
|
6
|
+
import akka.actor.ActorRef
|
7
|
+
import akka.io.Tcp.ConnectionClosed
|
8
|
+
|
9
|
+
<% for e in runtime.enums.values %>
|
10
|
+
/** <%= e.doc %> */
|
11
|
+
object <%= e.name %> extends Enumeration {
|
12
|
+
<% for v in e.elements.values %>
|
13
|
+
/** <%= v.doc %> */
|
14
|
+
val <%= v.name %> = Value(<%= v.value %>)
|
15
|
+
<% end %>}
|
16
|
+
<% end %>
|
17
|
+
<% for s in runtime.structs.values %>
|
18
|
+
/** <%= s.doc %> */
|
19
|
+
class <%= s.name %> extends Struct {
|
20
|
+
<% for m in s.members %>
|
21
|
+
/** <%= m.doc %> */
|
22
|
+
var <%= m.name %>: <%= m.type.scala %> = _
|
23
|
+
<% end %>
|
24
|
+
def this(<%= s.members.map { |m| m.name + ': ' + m.type.scala } .join ', ' %>) = {
|
25
|
+
this()<% for m in s.members %>
|
26
|
+
this.<%= m.name %> = <%= m.name %><% end %>
|
27
|
+
}
|
28
|
+
|
29
|
+
override def readFromPacket(packet: InPacket) = {<% for m in s.members %>
|
30
|
+
<%= m.name %> = <%= m.scala_read %><% end %>
|
31
|
+
}
|
32
|
+
|
33
|
+
override def writeToPacket(packet: OutPacket) = {<% for m in s.members %>
|
34
|
+
<%= m.scala_write %><% end %>
|
35
|
+
}
|
36
|
+
}
|
37
|
+
<% end %>
|
38
|
+
<% for n in runtime.get_node_directions node, :server %>
|
39
|
+
object <%= n.connection_name %> {
|
40
|
+
private object InMessage {<% for m in n.in_direction.messages.values %>
|
41
|
+
val <%= m.name %> = <%= m.id %><% end %>
|
42
|
+
}
|
43
|
+
|
44
|
+
private object OutMessage {<% for m in n.out_direction.messages.values %>
|
45
|
+
val <%= m.name %> = <%= m.id %><% end %>
|
46
|
+
}
|
47
|
+
<% for m in n.out_direction.messages.values %>
|
48
|
+
/** <%= m.doc %>
|
49
|
+
* <% for p in m.members %>
|
50
|
+
* @param <%= p.name %> <%= p.doc %><% end %>
|
51
|
+
*/
|
52
|
+
case class <%= m.name %>(<%= m.members.map { |p| p.name + ': ' + p.type.scala } .join ', ' %>)
|
53
|
+
<% end %>}
|
54
|
+
<% end %>
|
55
|
+
<% for n in runtime.get_node_directions node, :server %>
|
56
|
+
abstract class <%= n.connection_name %>(remote: ActorRef, address: InetSocketAddress) extends Connection(remote, address) {
|
57
|
+
import <%= n.connection_name %>._
|
58
|
+
|
59
|
+
override def processMessages(msg: Any): Unit = {
|
60
|
+
msg match {
|
61
|
+
case _: ConnectionClosed =>
|
62
|
+
this.onClose()
|
63
|
+
context.stop(self)<% for m in n.out_direction.messages.values %>
|
64
|
+
case <%= m.name %>(<%= m.members.map { |p| p.name } .join ', ' %>) =>
|
65
|
+
val packet = new OutPacket(OutMessage.<%= m.name %>)<% for p in m.members %>
|
66
|
+
<%= p.scala_write %><% end %>
|
67
|
+
this.sendPacket(packet)<% end %>
|
68
|
+
case other =>
|
69
|
+
this.selfReceive(other)
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
def processPacket(packet: InPacket) = {
|
74
|
+
packet.header match {<% for m in n.in_direction.messages.values %>
|
75
|
+
case InMessage.<%= m.name %> =><% for p in m.members %>
|
76
|
+
val <%= p.name %> = <%= p.scala_read %><% end %>
|
77
|
+
this.<%= m.scala_method %>(<%= m.members.map { |p| p.name } .join ', ' %>)<% end %>
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
/** Triggers when the connection closed
|
82
|
+
*
|
83
|
+
*/
|
84
|
+
def onClose()
|
85
|
+
<% for m in n.in_direction.messages.values %>
|
86
|
+
/** <%= m.doc %>
|
87
|
+
* <% for p in m.members %>
|
88
|
+
* @param <%= p.name %> <%= p.doc %><% end %>
|
89
|
+
*/
|
90
|
+
def <%= m.scala_method %>(<%= m.members.map { |p| p.name + ': ' + p.type.scala } .join ', ' %>)
|
91
|
+
<% end %>}
|
92
|
+
<% end %>
|