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.
@@ -0,0 +1,103 @@
1
+ using Brotorift;
2
+ using UnityEngine;
3
+ using System;
4
+ using System.Collections.Generic;
5
+ using System.Text;
6
+
7
+ namespace <%= node.namespace %>
8
+ {
9
+ #region Enums
10
+ <% for e in runtime.enums.values %>
11
+ /// <summary>
12
+ /// <%= e.doc %>
13
+ /// </summary>
14
+ public enum <%= e.name %>
15
+ {<% for v in e.elements.values %>
16
+ /// <summary>
17
+ /// <%= v.doc %>
18
+ /// </summary>
19
+ <%= v.name %> = <%= v.value %>,
20
+ <% end %>}
21
+ <% end %>
22
+ #endregion
23
+
24
+ #region Structs
25
+ <% for s in runtime.structs.values %>
26
+ /// <summary>
27
+ /// <%= s.doc %>
28
+ /// </summary>
29
+ public struct <%= s.name %> : IStruct
30
+ {<% for m in s.members %>
31
+ /// <summary>
32
+ /// <%= m.doc %>
33
+ /// </summary>
34
+ <%= m.unity_def %>
35
+ <% end %>
36
+ public <%= s.name %>( <%= s.members.map { |m| m.unity_param } .join ', ' %> )
37
+ {<% for m in s.members %>
38
+ this.<%= m.name %> = <%= m.name %>;<% end %>
39
+ }
40
+
41
+ public void ReadFromPacket( InPacket packet )
42
+ {<% for m in s.members %>
43
+ this.<%= m.unity_read %><% end %>
44
+ }
45
+
46
+ public void WriteToPacket( OutPacket packet )
47
+ {<% for m in s.members %>
48
+ <%= m.unity_write %><% end %>
49
+ }
50
+ }
51
+ <% end %>
52
+ #endregion
53
+ <% for node_direction in runtime.get_node_directions node, :client %>
54
+ public abstract class <%= node_direction.class_name %> : Client
55
+ {<% for m in node_direction.in_direction.messages.values %>
56
+ /// <summary>
57
+ /// <%= m.doc %>
58
+ /// </summary><% for p in m.members %>
59
+ /// <param name="<%= p.name %>"><%= p.doc %></param><% end %>
60
+ protected abstract <%= m.unity %>;<% end %>
61
+
62
+ public <%= node_direction.class_name %>()
63
+ {
64
+ }
65
+
66
+ private enum InMessage
67
+ {<% for m in node_direction.in_direction.messages.values %>
68
+ <%= m.name %> = <%= m.id %>,<% end %>
69
+ }
70
+
71
+ private enum OutMessage
72
+ {<% for m in node_direction.out_direction.messages.values %>
73
+ <%= m.name %> = <%= m.id %>,<% end %>
74
+ }
75
+ <% for m in node_direction.out_direction.messages.values %>
76
+ /// <summary>
77
+ /// <%= m.doc %>
78
+ /// </summary><% for p in m.members %>
79
+ /// <param name="<%= p.name %>"><%= p.doc %></param><% end %>
80
+ public <%= m.unity %>
81
+ {
82
+ var packet = new OutPacket( (int)OutMessage.<%= m.name %> );
83
+ <% for p in m.members %><%= p.unity_write %>
84
+ <% end %>this.SendPacket( packet );
85
+ }<% end %>
86
+
87
+ protected override void ProcessPacket( InPacket packet )
88
+ {
89
+ switch( (InMessage)packet.Header )
90
+ {<% for m in node_direction.in_direction.messages.values %>
91
+ case InMessage.<%= m.name %>:
92
+ {<% for p in m.members %>
93
+ var <%= p.unity_read %><% end %>
94
+ this.<%= m.name %>( <%= m.unity_param %> );
95
+ }
96
+ break;<% end %>
97
+ default:
98
+ break;
99
+ }
100
+ }
101
+ }
102
+ <% end %>
103
+ }
@@ -0,0 +1,188 @@
1
+ require 'erb'
2
+ require_relative '../case_helper'
3
+
4
+
5
+ class BuiltinTypeDef
6
+ def unity
7
+ case @name
8
+ when 'UShort'
9
+ return 'ushort'
10
+ when 'UInt'
11
+ return 'uint'
12
+ when 'ULong'
13
+ return 'ulong'
14
+ when 'DateTime'
15
+ return 'DateTime'
16
+ when 'ByteBuffer'
17
+ return 'byte[]'
18
+ when 'List'
19
+ return 'List'
20
+ when 'Set'
21
+ return 'HashSet'
22
+ when 'Map'
23
+ return 'Dictionary'
24
+ when 'Vector2', 'Vector3', 'Color'
25
+ return @name
26
+ when 'Matrix4'
27
+ return 'Matrix4x4'
28
+ else
29
+ return @name.decapitalize
30
+ end
31
+ end
32
+ end
33
+
34
+
35
+ class EnumTypeDef
36
+ def unity
37
+ @name
38
+ end
39
+ end
40
+
41
+
42
+ class StructTypeDef
43
+ def unity
44
+ @name
45
+ end
46
+ end
47
+
48
+
49
+ class TypeInstanceDef
50
+ @@lambda_index = 0
51
+
52
+ def unity
53
+ if @params.empty?
54
+ return @type.unity
55
+ else
56
+ return "#{@type.unity}#{unity_type_param}"
57
+ end
58
+ end
59
+
60
+ def unity_read is_top_scope
61
+ str = ''
62
+ if @type.is_a? StructTypeDef
63
+ str = "packet.ReadStruct( new #{@type.name}() )"
64
+ elsif @type.is_a? EnumTypeDef
65
+ str = "(#{@type.name})packet.ReadInt()"
66
+ else
67
+ str = "packet.Read#{unity_read_write}"
68
+ if @params.empty?
69
+ str += '()'
70
+ else
71
+ param_str = @params.map { |p| p.unity_read false } .join ', '
72
+ str += '( ' + param_str + ' )'
73
+ end
74
+ end
75
+
76
+ if is_top_scope == false
77
+ str = '() => ' + str
78
+ end
79
+
80
+ str
81
+ end
82
+
83
+ def unity_write member_name, is_top_scope
84
+ str = ''
85
+ if @type.is_a? StructTypeDef
86
+ str = "packet.WriteStruct( #{member_name} )"
87
+ elsif @type.is_a? EnumTypeDef
88
+ str = "packet.WriteInt( (int)#{member_name} )"
89
+ else
90
+ str = "packet.Write#{unity_read_write}"
91
+ if @params.empty?
92
+ str += "( #{member_name} )"
93
+ else
94
+ params_str = @params.map do |p|
95
+ @@lambda_index += 1
96
+ arg_name = '_' + @@lambda_index.to_s
97
+ p.unity_write arg_name, false
98
+ end
99
+ param_str = params_str.join ', '
100
+ str += "( #{member_name}, #{param_str} )"
101
+ end
102
+ end
103
+
104
+ if is_top_scope == false
105
+ str = "( #{member_name} ) => " + str
106
+ end
107
+
108
+ str
109
+ end
110
+
111
+ def unity_read_write
112
+ if @params.empty?
113
+ return @type.name
114
+ else
115
+ return "#{@type.name}#{unity_type_param}"
116
+ end
117
+ end
118
+
119
+ def unity_type_param
120
+ return '' if @params.empty?
121
+ param_str = @params.map { |p| p.unity } .join ', '
122
+ '<' + param_str + '>'
123
+ end
124
+ end
125
+
126
+
127
+ class MemberDef
128
+ def unity_def
129
+ "public #{unity_param};"
130
+ end
131
+
132
+ def unity_param
133
+ "#{@type.unity} #{@name}"
134
+ end
135
+
136
+ def unity_read
137
+ "#{@name} = #{@type.unity_read true};"
138
+ end
139
+
140
+ def unity_write
141
+ "#{@type.unity_write @name, true};"
142
+ end
143
+ end
144
+
145
+
146
+ class DirectionDef
147
+ def unity_name
148
+ "#{@client}#{@server}Connector"
149
+ end
150
+ end
151
+
152
+
153
+ class MessageDef
154
+ def unity
155
+ param_str = members.map { |m| m.unity_param } .join ', '
156
+ "void #{@name}( #{param_str} )"
157
+ end
158
+
159
+ def unity_param
160
+ members.map { |m| m.name } .join ', '
161
+ end
162
+ end
163
+
164
+
165
+ class NodeDirection
166
+ def class_name
167
+ "#{@remote.name}ConnectorBase"
168
+ end
169
+ end
170
+
171
+
172
+ class UnityClientGenerator < Generator
173
+ def initialize
174
+ super 'unity', :client
175
+ end
176
+
177
+ def generate node, runtime
178
+ folder = File.expand_path File.dirname __FILE__
179
+ erb_file = folder + '/unity_client_generator.cs.erb'
180
+ template = File.read erb_file
181
+ erb = ERB.new template
182
+ content = erb.result binding
183
+ File.write "#{node.name}.cs", content
184
+ end
185
+ end
186
+
187
+
188
+ Generator.add UnityClientGenerator.new
data/lib/lexer.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'rltk'
2
+
3
+
4
+ class Lexer < RLTK::Lexer
5
+ # Whitespace
6
+ rule(/\s/)
7
+
8
+ # Keyword
9
+ rule(/namespace/) { :NAMESPACE }
10
+ rule(/include/) { :INCLUDE }
11
+ rule(/node/) { :NODE }
12
+ rule(/as/) { :AS }
13
+ rule(/struct/) { :STRUCT }
14
+ rule(/enum/) { :ENUM }
15
+ rule(/direction/) { :DIRECTION }
16
+ rule(/message/) { :MESSAGE }
17
+ rule(/sequence/) { :SEQUENCE }
18
+ rule(/end/) { :END }
19
+
20
+ # Operator
21
+ rule(/\./) { :DOT }
22
+ rule(/\=/) { :ASSIGN }
23
+ rule(/<-/) { :LARROW }
24
+ rule(/->/) { :RARROW }
25
+ rule(/:/) { :COLON }
26
+ rule(/</) { :LANGLE }
27
+ rule(/>/) { :RANGLE }
28
+ rule(/,/) { :COMMA }
29
+
30
+ # Number
31
+ rule(/(\+|-)?\d+/) { |t| [:NUMBER, t.to_i] }
32
+ rule(/0[xX][0-9a-fA-F]+/) { |t| [:NUMBER, t.hex] }
33
+
34
+ # String
35
+ rule(/'.+'/) { |t| [:STRING, t[1..-2]] }
36
+
37
+ # Identifier
38
+ rule(/[A-Za-z_][A-Za-z0-9_]*/) { |t| [:IDENT, t] }
39
+
40
+ # Document
41
+ rule(/#.*/) { |t| [:DOCUMENT, t[1..-1].strip] }
42
+ end
data/lib/parser.rb ADDED
@@ -0,0 +1,105 @@
1
+ require 'rltk'
2
+ require_relative 'ast'
3
+
4
+
5
+ module RLTK
6
+ class Parser
7
+ class Environment
8
+ def position
9
+ Position.new @positions.first, @positions.last
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+
16
+ class Parser < RLTK::Parser
17
+ @@enum_value = 0
18
+
19
+ list(:decl_list, :decl)
20
+
21
+ production(:decl) do
22
+ clause('include_decl') { |d| d }
23
+ clause('node_decl') { |d| d }
24
+ clause('struct_decl') { |d| d }
25
+ clause('enum_decl') { |d| d }
26
+ clause('direction_decl') { |d| d }
27
+ clause('sequence_decl') { |d| d }
28
+ end
29
+
30
+ production(:include_decl) do
31
+ clause('INCLUDE STRING') { |_, filename| IncludeDecl.new self.position, filename }
32
+ end
33
+
34
+ production(:node_decl) do
35
+ clause('NODE IDENT IDENT doc') { |_, language, name, doc| NodeDecl.new self.position, name, language, name, '', doc }
36
+ clause('NODE IDENT IDENT AS IDENT doc') { |_, language, name, _, nickname, doc| NodeDecl.new self.position, name, language, nickname, '', doc }
37
+ clause('NODE IDENT IDENT NAMESPACE namespace doc') { |_, language, name, _, namespace, doc| NodeDecl.new self.position, name, language, name, namespace, doc }
38
+ clause('NODE IDENT IDENT AS IDENT NAMESPACE namespace doc') { |_, language, name, _, nickname, _, namespace, doc| NodeDecl.new self.position, name, language, nickname, namespace, doc }
39
+ end
40
+
41
+ production(:namespace) do
42
+ clause('IDENT') { |name| name }
43
+ clause('IDENT DOT namespace') { |name, _, rest| name + '.' + rest }
44
+ end
45
+
46
+ production(:doc) do
47
+ clause('') { || '' }
48
+ clause('DOCUMENT') { |doc| doc }
49
+ end
50
+
51
+ production(:struct_decl) do
52
+ clause('STRUCT IDENT doc member_list END') { |_, name, doc, members, _| StructDecl.new self.position, name, doc, members }
53
+ end
54
+
55
+ list(:member_list, :member)
56
+
57
+ production(:member) do
58
+ clause('type IDENT doc') { |type, name, doc| MemberDecl.new self.position, type, name, doc }
59
+ end
60
+
61
+ production(:type) do
62
+ clause('IDENT') { |name| TypeDecl.new self.position, name, [] }
63
+ clause('IDENT LANGLE type_param_list RANGLE') { |name, _, params, _| TypeDecl.new self.position, name, params }
64
+ end
65
+
66
+ nonempty_list(:type_param_list, :type, :COMMA)
67
+
68
+ production(:enum_decl) do
69
+ clause('ENUM IDENT doc element_list END') { |_, name, doc, elements, _| @@enum_value = 0; EnumDecl.new self.position, name, doc, elements }
70
+ end
71
+
72
+ list(:element_list, :element)
73
+
74
+ production(:element) do
75
+ clause('IDENT doc') { |name, doc| @@enum_value += 1; EnumElementDecl.new self.position, name, @@enum_value - 1, doc }
76
+ clause('IDENT ASSIGN NUMBER doc') { |name, _, value, doc| @@enum_value = value + 1; EnumElementDecl.new self.position, name, @@enum_value - 1, doc }
77
+ end
78
+
79
+ production(:direction_decl) do
80
+ clause('DIRECTION IDENT arrow IDENT doc message_list END') { |_, client, direction, server, doc, messages, _| DirectionDecl.new self.position, client, direction, server, doc, messages }
81
+ end
82
+
83
+ production(:arrow) do
84
+ clause('LARROW') { |_| :left }
85
+ clause('RARROW') { |_| :right }
86
+ end
87
+
88
+ list(:message_list, :message)
89
+
90
+ production(:message) do
91
+ clause('MESSAGE IDENT doc member_list END') { |_, name, doc, members, _| MessageDecl.new self.position, name, doc, members }
92
+ end
93
+
94
+ production(:sequence_decl) do
95
+ clause('SEQUENCE IDENT doc step_list END') { |_, name, doc, steps, _| SequenceDecl.new self.position, name, doc, steps }
96
+ end
97
+
98
+ list(:step_list, :step)
99
+
100
+ production(:step) do
101
+ clause('IDENT arrow IDENT COLON IDENT doc') { |client, direction, server, _, message, doc| StepDecl.new self.position, client, direction, server, message, doc }
102
+ end
103
+
104
+ finalize
105
+ end