brotorift 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b9f356872e186ceca556c1de43b78220131aac244cbe70635eb9c5c5fabcaf05
4
- data.tar.gz: 0c01b105e89a854b7ac7a596564fbe1c972e29e8c78f4484335f7a29a6e51e32
3
+ metadata.gz: 39731491bf8f75fd3020706e30be5bfeb20ce2ac29278a47c16554092d90724f
4
+ data.tar.gz: eb54a4e1e1b8925458fe1f33943a595e566360b06d2838d404ac903cc798b7a6
5
5
  SHA512:
6
- metadata.gz: aa37b5ac73dbea9fc4ba5e9ea5a918cce20460903a6b37e4c4b2348adf01a3ccdf2212b9e487c1a5c07d5aa8e468f9eeb62ffa107a5d10d3460f3206601a2c61
7
- data.tar.gz: c49c9580fcc4c6a99b75a8ece3f6633f52b99119768342fc995e51025e674fc55766b021634852da7d3a1c094733c98f715816a9566b12032caaa0c1f5246cec
6
+ metadata.gz: 7dfae3292bf18d45826429a411f930773b0277fb62051880d10d580d61417362cebcb3dbb6d49a5763734879528aef574b8021646955295efa21ee3096c813ea
7
+ data.tar.gz: fa60f4a94cc8a8cf060a922d4f3b4310e12c5f225a9a68770b896b6b4a6ee6669fca784cd039790f402139f1cd7917eb30df2d69e79fcd4aa8506e98d9895759
data/lib/brotorift.rb CHANGED
@@ -49,6 +49,7 @@ class Brotorift
49
49
  runtime.directions.each do |direction|
50
50
  generate_code runtime, direction.client, :client
51
51
  generate_code runtime, direction.server, :server
52
+ generate_bot_code runtime, direction.client
52
53
  end
53
54
 
54
55
  generate_sequence_diagrams runtime if generate_diagram
@@ -83,6 +84,17 @@ class Brotorift
83
84
  @generated_nodes[node.name] = [side]
84
85
  end
85
86
  end
87
+
88
+ def generate_bot_code runtime, node
89
+ generator = find_generator 'bot', :client
90
+ if generator == nil
91
+ puts "Generator for bot is not found.".red
92
+ return
93
+ end
94
+
95
+ puts "Generating bot code for node '#{node.name}'..."
96
+ generator.generate node, runtime
97
+ end
86
98
 
87
99
  def find_generator language, side
88
100
  Generator.generators.find { |g| g.language == language and g.side == side }
@@ -0,0 +1,102 @@
1
+ <% for n in runtime.get_node_directions node, :client %>
2
+ defmodule <%= node.namespace %>.<%= node.bot_client %> do
3
+ use GenServer
4
+
5
+ import <%= node.namespace %>.Enums
6
+
7
+ @version <%= runtime.version %>
8
+ <% for m in n.in_direction.messages.values %>
9
+ <%= m.bot_header_name %> <%= m.id %><% end %>
10
+ <% for m in n.out_direction.messages.values %>
11
+ <%= m.bot_header_name %> <%= m.id %><% end %>
12
+
13
+ def start_link(args) do
14
+ GenServer.start_link(__MODULE__, args)
15
+ end
16
+
17
+ def connect(client) do
18
+ GenServer.call(client, :connect, :infinity)
19
+ end
20
+
21
+ <% for m in n.out_direction.messages.values %>
22
+ @doc """
23
+ <%= m.doc %>
24
+
25
+ ## Parameters
26
+
27
+ - `client`: Bot client pid<% for p in m.members %>
28
+ - `<%= p.bot_name %>`: <%= p.doc %>
29
+ <% end %>
30
+ """
31
+ @spec <%= m.bot_send_name %>(client :: pid()<%= m.bot_params_with_types node %>) :: :ok
32
+ def <%= m.bot_send_name %>(client<%= m.bot_params %>) do
33
+ GenServer.cast(client, {:send, {:<%= m.bot_send_name %><%= m.bot_params %>}})
34
+ end
35
+ <% end %>
36
+
37
+ <% for m in n.in_direction.messages.values %>
38
+ @doc """
39
+ <%= m.doc %>
40
+
41
+ ## Parameters
42
+
43
+ - `client`: Bot client pid
44
+ """
45
+ @spec <%= m.bot_receive_name %>(client :: pid()) :: {:ok, {<%= m.bot_return_types node %>}}
46
+ def <%= m.bot_receive_name %>(client) do
47
+ GenServer.call(client, {:receive, :<%= m.bot_name %>}, :infinity)
48
+ end
49
+ <% end %>
50
+
51
+ def init(_args) do
52
+ {:ok, report} = BrotoriftBot.ReportManager.create_report()
53
+ {:ok, tcp_client} = BrotoriftBot.TcpClientSupervisor.create_client(report, self())
54
+ {:ok, {report, tcp_client}}
55
+ end
56
+
57
+ def handle_call(:connect, _from, {report, tcp_client}) do
58
+ BrotoriftBot.TcpClient.connect(tcp_client, @version)
59
+ {:reply, :ok, {report, tcp_client}}
60
+ end
61
+
62
+ <% for m in n.in_direction.messages.values %>
63
+ def handle_call({:receive, :<%= m.bot_name %>}, _from, {report, tcp_client}) do
64
+ start_time = Time.utc_now()
65
+ data = try_receive(<%= m.bot_header_name %>, tcp_client)
66
+ stop_time = Time.utc_now()
67
+ BrotoriftBot.Report.receive(report, :<%= m.bot_name %>, start_time, stop_time)
68
+
69
+ content = parse_packet(:<%= m.bot_name %>, data)
70
+ {:reply, {:ok, content}, {report, tcp_client}}
71
+ end
72
+ <% end %>
73
+ <% for m in n.out_direction.messages.values %>
74
+ def handle_cast({:send, {:<%= m.bot_send_name %><%= m.bot_params %>}}, {report, tcp_client}) do
75
+ data = <<<%= m.bot_header_name %>::32-little>><% for p in m.members %>
76
+ data = <%= p.type.bot_write node, p.bot_name %><% end %>
77
+ time = Time.utc_now()
78
+ :ok = BrotoriftBot.TcpClient.send_packet(tcp_client, data)
79
+ BrotoriftBot.Report.send(report, :<%= m.bot_name %>, time)
80
+ {:noreply, {report, tcp_client}}
81
+ end
82
+ <% end %>
83
+
84
+ defp try_receive(message, tcp_client) do
85
+ receive do
86
+ {^message, value} ->
87
+ value
88
+ _ ->
89
+ try_receive(message, tcp_client)
90
+ end
91
+ end
92
+
93
+ <% for m in n.in_direction.messages.values %>
94
+ defp parse_packet(:<%= m.bot_name %>, data) do<% for p in m.members %>
95
+ {data, <%= p.bot_name %>} = <%= p.type.bot_read node %><% end %>
96
+ <<>> = data
97
+ {<%= m.bot_returns %>}
98
+ end
99
+ <% end %>
100
+ end
101
+
102
+ <% end %>
@@ -0,0 +1,457 @@
1
+ require 'erb'
2
+ require_relative '../case_helper'
3
+
4
+ class EnumTypeDef
5
+ def bot_name
6
+ @name.underscore
7
+ end
8
+
9
+ def bot_read_name
10
+ "read_#{self.bot_name}"
11
+ end
12
+
13
+ def bot_write_name
14
+ "write_#{self.bot_name}"
15
+ end
16
+
17
+ def bot_read
18
+ "#{self.bot_read_name}(data)"
19
+ end
20
+
21
+ def bot_write member_name
22
+ "#{self.bot_write_name}(data, #{member_name})"
23
+ end
24
+
25
+ def bot_reader
26
+ "#{self.bot_read_name}/1"
27
+ end
28
+
29
+ def bot_writer
30
+ "#{self.bot_write_name}/2"
31
+ end
32
+
33
+ def bot_type
34
+ @elements.values.map { |e| e.bot_name } .join ' | '
35
+ end
36
+ end
37
+
38
+
39
+ class EnumElementDef
40
+ def bot_name
41
+ ':' + @name.underscore
42
+ end
43
+ end
44
+
45
+
46
+ class BuiltinTypeDef
47
+ def bot_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 bot_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 bot_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 bot_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 bot_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 bot_members
238
+ @members.map { |m| ":" + m.bot_name } .join ', '
239
+ end
240
+
241
+ def bot_members_with_types node
242
+ @members.map { |m| m.bot_name + ": " + m.type.bot_type(node) } .join ', '
243
+ end
244
+
245
+ def bot_members_with_values
246
+ @members.map { |m| m.bot_name + ": " + m.bot_name } .join ', '
247
+ end
248
+
249
+ def bot_type node
250
+ "#{node.namespace}.#{@name}.t"
251
+ end
252
+
253
+ def bot_read node
254
+ "#{node.namespace}.#{@name}.read(data)"
255
+ end
256
+
257
+ def bot_write node, member_name
258
+ "#{node.namespace}.#{@name}.write(data, #{member_name})"
259
+ end
260
+
261
+ def bot_reader node
262
+ "&#{node.namespace}.#{@name}.read/1"
263
+ end
264
+
265
+ def bot_writer node
266
+ "&#{node.namespace}.#{@name}.write/2"
267
+ end
268
+ end
269
+
270
+
271
+ class TypeInstanceDef
272
+ def bot_type node
273
+ return self.bot_list node if @type.name == 'List'
274
+ return self.bot_set node if @type.name == 'Set'
275
+ return self.bot_map node if @type.name == 'Map'
276
+ return @type.bot_type if @type.is_a? BuiltinTypeDef or @type.is_a? EnumTypeDef
277
+ return @type.bot_type node if @type.is_a? StructTypeDef
278
+ end
279
+
280
+ def bot_read node
281
+ return self.bot_list_read node if @type.name == 'List'
282
+ return self.bot_set_read node if @type.name == 'Set'
283
+ return self.bot_map_read node if @type.name == 'Map'
284
+ return @type.bot_read if @type.is_a? BuiltinTypeDef or @type.is_a? EnumTypeDef
285
+ return @type.bot_read node if @type.is_a? StructTypeDef
286
+ end
287
+
288
+ def bot_write node, member_name
289
+ return self.bot_list_write node, member_name if @type.name == 'List'
290
+ return self.bot_set_write node, member_name if @type.name == 'Set'
291
+ return self.bot_map_write node, member_name if @type.name == 'Map'
292
+ return @type.bot_write member_name if @type.is_a? BuiltinTypeDef or @type.is_a? EnumTypeDef
293
+ return @type.bot_write node, member_name if @type.is_a? StructTypeDef
294
+ end
295
+
296
+ def bot_reader node
297
+ return self.bot_list_reader node if @type.name == 'List'
298
+ return self.bot_set_reader node if @type.name == 'Set'
299
+ return self.bot_map_reader node if @type.name == 'Map'
300
+ return @type.bot_reader if @type.is_a? BuiltinTypeDef or @type.is_a? EnumTypeDef
301
+ return @type.bot_reader node if @type.is_a? StructTypeDef
302
+ end
303
+
304
+ def bot_writer node
305
+ return self.bot_list_writer node if @type.name == 'List'
306
+ return self.bot_set_writer node if @type.name == 'Set'
307
+ return self.bot_map_writer node if @type.name == 'Map'
308
+ return @type.bot_writer if @type.is_a? BuiltinTypeDef or @type.is_a? EnumTypeDef
309
+ return @type.bot_writer node if @type.is_a? StructTypeDef
310
+ end
311
+
312
+ def bot_list node
313
+ 'list(' + @params[0].bot_type(node) + ')'
314
+ end
315
+
316
+ def bot_list_read node
317
+ 'Brotorift.Binary.read_list(data, ' + @params[0].bot_reader(node) + ')'
318
+ end
319
+
320
+ def bot_list_write node, member_name
321
+ 'Brotorift.Binary.write_list(data, ' + member_name + ', ' + @params[0].bot_writer(node) + ')'
322
+ end
323
+
324
+ def bot_list_reader node
325
+ '&Brotorift.Binary.read_list(&1, ' + @params[0].bot_reader(node) + ')'
326
+ end
327
+
328
+ def bot_list_writer node
329
+ '&Brotorift.Binary.write_list(&1, &2, ' + @params[0].bot_writer(node) + ')'
330
+ end
331
+
332
+ def bot_set node
333
+ 'MapSet.t(' + @params[0].bot_type(node) + ')'
334
+ end
335
+
336
+ def bot_set_read node
337
+ 'Brotorift.Binary.read_set(data, ' + @params[0].bot_reader(node) + ')'
338
+ end
339
+
340
+ def bot_set_write node, member_name
341
+ 'Brotorift.Binary.write_set(data, ' + member_name + ', ' + @params[0].bot_writer(node) + ')'
342
+ end
343
+
344
+ def bot_set_reader node
345
+ '&Brotorift.Binary.read_set(&1, ' + @params[0].bot_reader(node) + ')'
346
+ end
347
+
348
+ def bot_set_writer node
349
+ '&Brotorift.Binary.write_set(&1, &2, ' + @params[0].bot_writer(node) + ')'
350
+ end
351
+
352
+ def bot_map node
353
+ '%{' + @params[0].bot_type(node) + ' => ' + @params[1].bot_type(node) + '}'
354
+ end
355
+
356
+ def bot_map_read node
357
+ 'Brotorift.Binary.read_map(data, ' + @params[0].bot_reader(node) + ', ' + @params[1].bot_reader(node) + ')'
358
+ end
359
+
360
+ def bot_map_write node, member_name
361
+ 'Brotorift.Binary.write_map(data, ' + member_name + ', ' + @params[0].bot_writer(node) + ', ' + @params[1].bot_writer(node) + ')'
362
+ end
363
+
364
+ def bot_map_reader node
365
+ '&Brotorift.Binary.read_map(&1, ' + @params[0].bot_reader(node) + ', ' + @params[1].bot_reader(node) + ')'
366
+ end
367
+
368
+ def bot_map_writer node
369
+ '&Brotorift.Binary.write_map(&1, &2, ' + @params[0].bot_writer(node) + ', ' + @params[1].bot_writer(node) + ')'
370
+ end
371
+ end
372
+
373
+
374
+ class MemberDef
375
+ def bot_name
376
+ @name.underscore
377
+ end
378
+ end
379
+
380
+
381
+ class MessageDef
382
+ def bot_header_name
383
+ "@header_#{self.bot_name}"
384
+ end
385
+
386
+ def bot_name
387
+ @name.underscore
388
+ end
389
+
390
+ def bot_send_name
391
+ "send_#{self.bot_name}"
392
+ end
393
+
394
+ def bot_receive_name
395
+ "receive_#{self.bot_name}"
396
+ end
397
+
398
+ def bot_params
399
+ return '' if members.empty?
400
+ params = members.map { |m| m.bot_name } .join ', '
401
+ ', ' + params
402
+ end
403
+
404
+ def bot_returns
405
+ return '' if members.empty?
406
+ members.map { |m| m.bot_name } .join ', '
407
+ end
408
+
409
+ def bot_params_with_types node
410
+ return '' if members.empty?
411
+ params = members.map { |m| m.bot_name + ' :: ' + m.type.bot_type(node) } .join ', '
412
+ ', ' + params
413
+ end
414
+
415
+ def bot_return_types node
416
+ return '' if members.empty?
417
+ members.map { |m| m.type.bot_type(node) }.join ', '
418
+ end
419
+ end
420
+
421
+
422
+ class NodeDef
423
+ def bot_name
424
+ @name.underscore
425
+ end
426
+
427
+ def bot_client
428
+ @name + 'BotClient'
429
+ end
430
+ end
431
+
432
+
433
+ class BotGenerator < Generator
434
+ def initialize
435
+ super 'bot', :client
436
+ end
437
+
438
+ def generate node, runtime
439
+ self.generate_file node, runtime, 'bot_types_generator', "#{node.bot_name}_types"
440
+ self.generate_file node, runtime, 'bot_generator', node.bot_name
441
+ end
442
+
443
+ def generate_file node, runtime, template_file, generated_file
444
+ folder = File.expand_path File.dirname __FILE__
445
+ erb_file = folder + "/#{template_file}.ex.erb"
446
+ template = File.read erb_file
447
+ erb = ERB.new template
448
+ content = erb.result binding
449
+
450
+ output_dir = File.dirname runtime.filename
451
+ output_path = File.join output_dir, "#{generated_file}_bot.ex"
452
+ File.write output_path, content
453
+ end
454
+ end
455
+
456
+
457
+ Generator.add BotGenerator.new
@@ -0,0 +1,40 @@
1
+ defmodule <%= node.namespace %>.Enums do<% for e in runtime.enums.values %>
2
+ def <%= e.bot_read_name %>(data) do
3
+ <<value::32-little, data::binary>> = data
4
+ case value do<% for v in e.elements.values %>
5
+ <%= v.value %> -> {data, <%= v.bot_name %>}<% end %>
6
+ _ -> :error
7
+ end
8
+ end
9
+
10
+ def <%= e.bot_write_name %>(data, value) do
11
+ case value do<% for v in e.elements.values %>
12
+ <%= v.bot_name %> -> <<data::binary, <%= v.value %>::32-little>><% end %>
13
+ _ -> :error
14
+ end
15
+ end
16
+ <% end %>end
17
+
18
+ <% for s in runtime.structs.values %>
19
+ defmodule <%= node.namespace %>.<%= s.name %> do
20
+ defstruct [<%= s.bot_members %>]
21
+
22
+ import <%= node.namespace %>.Enums
23
+
24
+ @typedoc """
25
+ <%= s.doc %><% for m in s.members %>
26
+ `:<%= m.bot_name %>`: <%= m.doc %><% end %>
27
+ """
28
+ @type t :: %<%= node.namespace %>.<%= s.name %>{<%= s.bot_members_with_types node %>}
29
+
30
+ def read(data) do<% for m in s.members %>
31
+ {data, <%= m.bot_name %>} = <%= m.type.bot_read node %><% end %>
32
+ {data, %<%= node.namespace %>.<%= s.name %>{<%= s.bot_members_with_values %>}}
33
+ end
34
+
35
+ def write(data, value) do<% for m in s.members %>
36
+ data = <%= m.type.bot_write node, 'value.' + m.bot_name %><% end %>
37
+ data
38
+ end
39
+ end
40
+ <% end %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brotorift
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ren
@@ -65,6 +65,9 @@ files:
65
65
  - lib/case_helper.rb
66
66
  - lib/compiler.rb
67
67
  - lib/compiler_error.rb
68
+ - lib/generators/bot_generator.ex.erb
69
+ - lib/generators/bot_generator.rb
70
+ - lib/generators/bot_types_generator.ex.erb
68
71
  - lib/generators/elixir_server_generator.ex.erb
69
72
  - lib/generators/elixir_server_generator.rb
70
73
  - lib/generators/elixir_server_types_generator.ex.erb