source: EcnlProtoTool/trunk/webapp/webmrbc/Ecnl/EcnlTaskBlock.cs@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csharp
File size: 10.9 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using Bridge;
6using Bridge.Html5;
7using Bridge.jQuery2;
8
9namespace WebMrbc
10{
11 internal class EcnlTaskWorkspace : IClassWorkspace
12 {
13 BlocklyView view;
14 internal Workspace workspace;
15 private Ruby _RubyCode;
16
17 public string Identifier { get { return view.Identifier; } }
18 public Workspace Workspace { get { return workspace; } }
19 public BlocklyView View { get { return view; } }
20 public Ruby RubyCode { get { return _RubyCode; } }
21
22 public EcnlTaskWorkspace(BlocklyView view)
23 {
24 this.view = view;
25 workspace = view.Init();
26 }
27
28 public string GetImageUrl()
29 {
30 return "img/no_image.png";
31 }
32
33 public bool IsPreset()
34 {
35 return true;
36 }
37
38 public string ToCode(string filename)
39 {
40 if (Collections.LocalNode == null)
41 return "";
42
43 _RubyCode = new Ruby(filename);
44 var enode = Collections.LocalNode.enode;
45 var objects = new JsonObjectInfo[0];
46 foreach (var item in Collections.ClassWorkspaces) {
47 var obj = item as EObjectWorkspace;
48 if ((obj == null) || (obj == Collections.LocalNode))
49 continue;
50
51 objects.Push(obj.eobject);
52 }
53 enode.objects = objects;
54 var result = _RubyCode.defineEcnlTask(this, enode);
55 view.Changed = false;
56 return result;
57 }
58
59 //Element ele;
60
61 public void Activate()
62 {
63 //ele = Blockly.Xml.workspaceToDom(workspace);
64 }
65
66 public void Inactivate()
67 {
68 //workspace.clear();
69 //Blockly.Xml.domToWorkspace(ele, workspace);
70 }
71
72 public void ReloadToolbox(HTMLElement toolbox)
73 {
74 toolbox.AppendChild(Document.CreateElement("sep"));
75 var xml = jQuery.ParseXML(App.ArduinoToolbox);
76 var categories = xml.ChildNodes[0];
77 foreach (var item in categories.ChildNodes) {
78 if (item.NodeName != "category")
79 continue;
80 toolbox.AppendChild(item);
81 }
82
83 toolbox.AppendChild(Document.CreateElement("sep"));
84 xml = jQuery.ParseXML(App.EcnlToolbox);
85 categories = xml.ChildNodes[0];
86 foreach (var item in categories.ChildNodes) {
87 if (item.NodeName != "category")
88 continue;
89 toolbox.AppendChild(item);
90 }
91
92 var category = Document.CreateElement("category");
93 category.SetAttribute("name", "ECNL SvcTask");
94 category.SetAttribute("colour", "230");
95 toolbox.AppendChild(category);
96
97 var funcs = new[] { "setup", "recv_esv", "break_wait", "timeout", "snd_msg" };
98 var procs = new[] { "is_local_addr", "is_multicast_addr", "is_valid_addrid", "get_local_addr", "get_multicast_addr", "get_remote_addr", "get_remote_id", "set_remote_addr", "add_remote_addr" };
99 foreach (var name in funcs) {
100 var block = Document.CreateElement("block");
101 block.SetAttribute("type", ProceduresDefnoreturnBlock.type_name);
102
103 var field = Document.CreateElement("field");
104 field.SetAttribute("name", "NAME");
105 field.AppendChild(Document.CreateTextNode(name));
106 block.AppendChild(field);
107
108 category.AppendChild(block);
109 }
110
111 foreach (var name in procs) {
112 var block = Document.CreateElement("block");
113 block.SetAttribute("type", ProceduresDefreturnBlock.type_name);
114
115 var field = Document.CreateElement("field");
116 field.SetAttribute("name", "NAME");
117 field.AppendChild(Document.CreateTextNode(name));
118 block.AppendChild(field);
119
120 category.AppendChild(block);
121 }
122 }
123
124 public void OpenModifyView(Action<bool> callback)
125 {
126 view.ReloadToolbox(this);
127 callback(true);
128 }
129
130 public string Template(string template)
131 {
132 template = template.Replace("%identifier%", Identifier);
133 template = template.Replace("%attribute%", "SvcTask");
134 template = template.Replace("%img%", GetImageUrl());
135 return template;
136 }
137 }
138
139 partial class Ruby
140 {
141 internal string defineEcnlTask(EcnlTaskWorkspace workspace, JsonNodeInfo localNode)
142 {
143 global = false;
144 string code = workspaceToCode(workspace.Workspace);
145 global = true;
146
147 var identifier = workspace.Identifier;
148 var funcs = new string[0];
149
150 var blocks = workspace.Workspace.getTopBlocks(true);
151 for (var i = 0; i < blocks.Length; i++) {
152 var block = blocks[i];
153 string name;
154
155 switch (block.type) {
156 case ProceduresDefnoreturnBlock.type_name:
157 name = block.getFieldValue("NAME");
158 switch (name) {
159 case "setup":
160 case "recv_esv":
161 case "break_wait":
162 case "timeout":
163 case "snd_msg":
164 funcs.Push(name);
165 break;
166 }
167 break;
168 case ProceduresDefreturnBlock.type_name:
169 name = block.getFieldValue("NAME");
170 switch (name) {
171 case "is_local_addr":
172 case "is_multicast_addr":
173 case "is_valid_addrid":
174 case "get_local_addr":
175 case "get_multicast_addr":
176 case "get_remote_addr":
177 case "get_remote_id":
178 case "set_remote_addr":
179 case "add_remote_addr":
180 funcs.Push(name);
181 break;
182 }
183 break;
184 }
185 }
186
187 var sb = new StringBuilder();
188
189 sb.AppendLine("class " + identifier + " < ECNL::SvcTask");
190 sb.AppendLine(" def initialize()");
191 sb.AppendLine(" @profile = " + localNode.identifier + ".new(" + localNode.instanceCode + ")");
192 switch (localNode.objects.Length) {
193 case 0:
194 sb.AppendLine(" @devices = []");
195 break;
196 case 1: {
197 var o = localNode.objects[0];
198 sb.AppendLine(" @devices = [ " + o.identifier + ".new(" + o.instanceCode + ", @profile) ]");
199 }
200 break;
201 default:
202 sb.AppendLine(" @devices = [");
203 foreach (var o in localNode.objects) {
204 sb.AppendLine(" " + o.identifier + ".new(" + o.instanceCode + ", @profile)");
205 }
206 sb.AppendLine(" ]");
207 break;
208 }
209 sb.AppendLine(" @enodadrb_table = []");
210 sb.AppendLine();
211 sb.AppendLine(" super()");
212 if (funcs.Contains("setup")) {
213 sb.AppendLine();
214 sb.AppendLine(" setup()");
215 }
216 sb.AppendLine(" end");
217 sb.AppendLine();
218 foreach (var line in code.Split("\n")) {
219 sb.AppendLine("\t" + line);
220 }
221 sb.AppendLine();
222 if (!funcs.Contains("recv_esv")) {
223 sb.AppendLine(" def recv_esv(esv)");
224 sb.AppendLine(" end");
225 }
226 sb.AppendLine();
227 if (!funcs.Contains("break_wait")) {
228 sb.AppendLine(" def break_wait(data)");
229 sb.AppendLine(" end");
230 }
231 sb.AppendLine();
232 if (!funcs.Contains("timeout")) {
233 sb.AppendLine(" def timeout()");
234 sb.AppendLine(" end");
235 }
236 sb.AppendLine();
237 if (!funcs.Contains("snd_msg")) {
238 sb.AppendLine(" def snd_msg(ep, data)");
239 sb.AppendLine(" # 通信レイヤーへ送信");
240 sb.AppendLine(" TargetBoard::snd_msg(ep, data)");
241 sb.AppendLine(" end");
242 }
243 sb.AppendLine();
244 if (!funcs.Contains("is_local_addr")) {
245 sb.AppendLine(" def is_local_addr(ep)");
246 sb.AppendLine(" TargetBoard::is_local_addr(ep)");
247 sb.AppendLine(" end");
248 }
249 sb.AppendLine();
250 if (!funcs.Contains("is_multicast_addr")) {
251 sb.AppendLine(" def is_multicast_addr(ep)");
252 sb.AppendLine(" TargetBoard::is_multicast_addr(ep)");
253 sb.AppendLine(" end");
254 }
255 sb.AppendLine();
256 if (!funcs.Contains("is_valid_addrid")) {
257 sb.AppendLine(" def is_valid_addrid(id)");
258 sb.AppendLine(" (id >= 0) && ((id - ECNL::ENOD_REMOTE_ID) < @enodadrb_table.length)");
259 sb.AppendLine(" end");
260 }
261 sb.AppendLine();
262 if (!funcs.Contains("get_local_addr")) {
263 sb.AppendLine(" def get_local_addr()");
264 sb.AppendLine(" TargetBoard::get_local_addr()");
265 sb.AppendLine(" end");
266 }
267 sb.AppendLine();
268 if (!funcs.Contains("get_multicast_addr")) {
269 sb.AppendLine(" def get_multicast_addr()");
270 sb.AppendLine(" TargetBoard::get_multicast_addr()");
271 sb.AppendLine(" end");
272 }
273 sb.AppendLine();
274 if (!funcs.Contains("get_remote_addr")) {
275 sb.AppendLine(" def get_remote_addr(id)");
276 sb.AppendLine(" index = id - ECNL::ENOD_REMOTE_ID");
277 sb.AppendLine(" if (index < 0) || (index >= @enodadrb_table.length)");
278 sb.AppendLine(" nil");
279 sb.AppendLine(" else");
280 sb.AppendLine(" @enodadrb_table[index]");
281 sb.AppendLine(" end");
282 sb.AppendLine(" end");
283 }
284 sb.AppendLine();
285 if (!funcs.Contains("get_remote_id")) {
286 sb.AppendLine(" # 通信レイヤーアドレスの同じものを検索");
287 sb.AppendLine(" def get_remote_id(ep)");
288 sb.AppendLine(" id = ECNL::ENOD_REMOTE_ID - 1");
289 sb.AppendLine(" for ea in @enodadrb_table do");
290 sb.AppendLine(" id += 1");
291 sb.AppendLine(" if !ea then");
292 sb.AppendLine(" next");
293 sb.AppendLine(" end");
294 sb.AppendLine(" if !TargetBoard::equals_addr(ea, ep) then");
295 sb.AppendLine(" next");
296 sb.AppendLine(" end");
297 sb.AppendLine();
298 sb.AppendLine(" return id");
299 sb.AppendLine(" end");
300 sb.AppendLine();
301 sb.AppendLine(" return ECNL::ENOD_NOT_MATCH_ID");
302 sb.AppendLine(" end");
303 }
304 sb.AppendLine();
305 if (!funcs.Contains("set_remote_addr")) {
306 sb.AppendLine(" # 対応するリモートノードを検索");
307 sb.AppendLine(" def set_remote_addr(edata, ep)");
308 sb.AppendLine(" id = ECNL::ENOD_REMOTE_ID - 1");
309 sb.AppendLine(" for ea in @enodadrb_table do");
310 sb.AppendLine(" id += 1");
311 sb.AppendLine(" if !ea then");
312 sb.AppendLine(" next");
313 sb.AppendLine(" end");
314 sb.AppendLine(" if !is_match(svc, edata, ep) then");
315 sb.AppendLine(" next");
316 sb.AppendLine(" end");
317 sb.AppendLine();
318 sb.AppendLine(" # 対応するリモートノードがあれば通信レイヤーアドレスを設定");
319 sb.AppendLine(" @enodadrb_table[id - ECNL::ENOD_REMOTE_ID] = ep");
320 sb.AppendLine();
321 sb.AppendLine(" return id");
322 sb.AppendLine(" end");
323 sb.AppendLine();
324 sb.AppendLine(" return ECNL::ENOD_NOT_MATCH_ID");
325 sb.AppendLine(" end");
326 }
327 sb.AppendLine();
328 if (!funcs.Contains("add_remote_addr")) {
329 sb.AppendLine(" # 空き領域を探して自動登録");
330 sb.AppendLine(" def add_remote_addr(edata, ep)");
331 sb.AppendLine(" id = ECNL::ENOD_REMOTE_ID - 1");
332 sb.AppendLine(" for ea in @enodadrb_table do");
333 sb.AppendLine(" id += 1");
334 sb.AppendLine(" if ea then");
335 sb.AppendLine(" next");
336 sb.AppendLine(" end");
337 sb.AppendLine();
338 sb.AppendLine(" @enodadrb_table[id - ECNL::ENOD_REMOTE_ID] = ep");
339 sb.AppendLine();
340 sb.AppendLine(" return id");
341 sb.AppendLine(" end");
342 sb.AppendLine();
343 sb.AppendLine(" if @enodadrb_table.length >= 100 then");
344 sb.AppendLine(" return ECNL::ENOD_NOT_MATCH_ID");
345 sb.AppendLine(" end");
346 sb.AppendLine();
347 sb.AppendLine(" id = @enodadrb_table.length;");
348 sb.AppendLine(" @enodadrb_table[id] = ep");
349 sb.AppendLine();
350 sb.AppendLine(" return id + ECNL::ENOD_REMOTE_ID");
351 sb.AppendLine(" end");
352 sb.AppendLine("end");
353
354 code = sb.ToString();
355 }
356 return code;
357 }
358
359 string itr_code()
360 {
361 var sb = new StringBuilder();
362
363 sb.AppendLine("itr = esv.itr_ini()");
364 sb.AppendLine("itr.itr_nxt()");
365 sb.AppendLine("until itr.is_eof do");
366 sb.AppendLine(" if itr.epc == 0xD6 then");
367 sb.AppendLine(" # LEDをON");
368 sb.AppendLine(" digitalWrite(2, 1)");
369 sb.AppendLine(" end");
370 sb.AppendLine(" itr.itr_nxt()");
371 sb.AppendLine("end");
372
373 return sb.ToString();
374 }
375 }
376}
Note: See TracBrowser for help on using the repository browser.