brotorift 0.8.0 → 0.9.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 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