brotorift 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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