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

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

ファイルヘッダーコメントを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csharp
File size: 13.3 KB
Line 
1/*
2 * TOPPERS/ECNL Prototyping tool
3 *
4 * Copyright (C) 2017 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id: EcnlTaskBlock.cs 287 2017-05-05 14:22:23Z coas-nagasima $
36 */
37using System;
38using System.Collections.Generic;
39using System.Linq;
40using System.Text;
41using Bridge;
42using Bridge.Html5;
43using Bridge.jQuery2;
44
45namespace WebMrbc
46{
47 internal class EcnlTaskWorkspace : IClassWorkspace
48 {
49 BlocklyView view;
50 internal Workspace workspace;
51 private Ruby _RubyCode;
52
53 public string Identifier { get { return view.Identifier; } }
54 public Workspace Workspace { get { return workspace; } }
55 public BlocklyView View { get { return view; } }
56 public Ruby RubyCode { get { return _RubyCode; } }
57
58 public EcnlTaskWorkspace(BlocklyView view)
59 {
60 this.view = view;
61 workspace = view.Init();
62 }
63
64 public string GetImageUrl()
65 {
66 return "img/no_image.png";
67 }
68
69 public bool IsPreset()
70 {
71 return true;
72 }
73
74 public string ToCode(string filename)
75 {
76 if (Collections.LocalNode == null)
77 return "";
78
79 _RubyCode = new Ruby(filename);
80 var enode = Collections.LocalNode.enode;
81 var objects = new JsonObjectInfo[0];
82 foreach (var item in Collections.ClassWorkspaces) {
83 var obj = item as EObjectWorkspace;
84 if ((obj == null) || (obj == Collections.LocalNode))
85 continue;
86
87 objects.Push(obj.eobject);
88 }
89 enode.objects = objects;
90 var result = _RubyCode.defineEcnlTask(this, enode);
91 view.Changed = false;
92 return result;
93 }
94
95 //Element ele;
96
97 public void Activate()
98 {
99 //ele = Blockly.Xml.workspaceToDom(workspace);
100 }
101
102 public void Inactivate()
103 {
104 //workspace.clear();
105 //Blockly.Xml.domToWorkspace(ele, workspace);
106 }
107
108 public void ReloadToolbox(HTMLElement toolbox)
109 {
110 toolbox.AppendChild(Document.CreateElement("sep"));
111 var xml = jQuery.ParseXML(App.ArduinoToolbox);
112 var categories = xml.ChildNodes[0];
113 foreach (var item in categories.ChildNodes) {
114 if (item.NodeName != "category")
115 continue;
116 toolbox.AppendChild(item);
117 }
118
119 toolbox.AppendChild(Document.CreateElement("sep"));
120 xml = jQuery.ParseXML(App.EcnlToolbox);
121 categories = xml.ChildNodes[0];
122 foreach (var item in categories.ChildNodes) {
123 if (item.NodeName != "category")
124 continue;
125 toolbox.AppendChild(item);
126 }
127
128 var category = Document.CreateElement("category");
129 category.SetAttribute("name", "ECNL SvcTask");
130 category.SetAttribute("colour", "230");
131 toolbox.AppendChild(category);
132
133 var funcs = new[] { "setup", "recv_esv", "break_wait", "timeout", "snd_msg" };
134 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" };
135 foreach (var name in funcs) {
136 var block = Document.CreateElement("block");
137 block.SetAttribute("type", ProceduresDefnoreturnBlock.type_name);
138
139 var field = Document.CreateElement("field");
140 field.SetAttribute("name", "NAME");
141 field.AppendChild(Document.CreateTextNode(name));
142 block.AppendChild(field);
143
144 category.AppendChild(block);
145 }
146
147 foreach (var name in procs) {
148 var block = Document.CreateElement("block");
149 block.SetAttribute("type", ProceduresDefreturnBlock.type_name);
150
151 var field = Document.CreateElement("field");
152 field.SetAttribute("name", "NAME");
153 field.AppendChild(Document.CreateTextNode(name));
154 block.AppendChild(field);
155
156 category.AppendChild(block);
157 }
158 }
159
160 public void OpenModifyView(Action<bool> callback)
161 {
162 view.ReloadToolbox(this);
163 callback(true);
164 }
165
166 public string Template(string template)
167 {
168 template = template.Replace("%identifier%", Identifier);
169 template = template.Replace("%attribute%", "SvcTask");
170 template = template.Replace("%img%", GetImageUrl());
171 return template;
172 }
173 }
174
175 partial class Ruby
176 {
177 internal string defineEcnlTask(EcnlTaskWorkspace workspace, JsonNodeInfo localNode)
178 {
179 global = false;
180 string code = workspaceToCode(workspace.Workspace);
181 global = true;
182
183 var identifier = workspace.Identifier;
184 var funcs = new string[0];
185
186 var blocks = workspace.Workspace.getTopBlocks(true);
187 for (var i = 0; i < blocks.Length; i++) {
188 var block = blocks[i];
189 string name;
190
191 switch (block.type) {
192 case ProceduresDefnoreturnBlock.type_name:
193 name = block.getFieldValue("NAME");
194 switch (name) {
195 case "setup":
196 case "recv_esv":
197 case "break_wait":
198 case "timeout":
199 case "snd_msg":
200 funcs.Push(name);
201 break;
202 }
203 break;
204 case ProceduresDefreturnBlock.type_name:
205 name = block.getFieldValue("NAME");
206 switch (name) {
207 case "is_local_addr":
208 case "is_multicast_addr":
209 case "is_valid_addrid":
210 case "get_local_addr":
211 case "get_multicast_addr":
212 case "get_remote_addr":
213 case "get_remote_id":
214 case "set_remote_addr":
215 case "add_remote_addr":
216 funcs.Push(name);
217 break;
218 }
219 break;
220 }
221 }
222
223 var sb = new StringBuilder();
224
225 sb.AppendLine("class " + identifier + " < ECNL::SvcTask");
226 sb.AppendLine(" def initialize()");
227 sb.AppendLine(" @profile = " + localNode.identifier + ".new(" + localNode.instanceCode + ")");
228 switch (localNode.objects.Length) {
229 case 0:
230 sb.AppendLine(" @devices = []");
231 break;
232 case 1: {
233 var o = localNode.objects[0];
234 sb.AppendLine(" @devices = [ " + o.identifier + ".new(" + o.instanceCode + ", @profile) ]");
235 }
236 break;
237 default:
238 sb.AppendLine(" @devices = [");
239 foreach (var o in localNode.objects) {
240 sb.AppendLine(" " + o.identifier + ".new(" + o.instanceCode + ", @profile)");
241 }
242 sb.AppendLine(" ]");
243 break;
244 }
245 sb.AppendLine(" @enodadrb_table = []");
246 sb.AppendLine();
247 sb.AppendLine(" super()");
248 if (funcs.Contains("setup")) {
249 sb.AppendLine();
250 sb.AppendLine(" setup()");
251 }
252 sb.AppendLine(" end");
253 sb.AppendLine();
254 foreach (var line in code.Split("\n")) {
255 sb.AppendLine("\t" + line);
256 }
257 sb.AppendLine();
258 if (!funcs.Contains("recv_esv")) {
259 sb.AppendLine(" def recv_esv(esv)");
260 sb.AppendLine(" end");
261 }
262 sb.AppendLine();
263 if (!funcs.Contains("break_wait")) {
264 sb.AppendLine(" def break_wait(data)");
265 sb.AppendLine(" end");
266 }
267 sb.AppendLine();
268 if (!funcs.Contains("timeout")) {
269 sb.AppendLine(" def timeout()");
270 sb.AppendLine(" end");
271 }
272 sb.AppendLine();
273 if (!funcs.Contains("snd_msg")) {
274 sb.AppendLine(" def snd_msg(ep, data)");
275 sb.AppendLine(" # 通信レイヤーへ送信");
276 sb.AppendLine(" TargetBoard::snd_msg(ep, data)");
277 sb.AppendLine(" end");
278 }
279 sb.AppendLine();
280 if (!funcs.Contains("is_local_addr")) {
281 sb.AppendLine(" def is_local_addr(ep)");
282 sb.AppendLine(" TargetBoard::is_local_addr(ep)");
283 sb.AppendLine(" end");
284 }
285 sb.AppendLine();
286 if (!funcs.Contains("is_multicast_addr")) {
287 sb.AppendLine(" def is_multicast_addr(ep)");
288 sb.AppendLine(" TargetBoard::is_multicast_addr(ep)");
289 sb.AppendLine(" end");
290 }
291 sb.AppendLine();
292 if (!funcs.Contains("is_valid_addrid")) {
293 sb.AppendLine(" def is_valid_addrid(id)");
294 sb.AppendLine(" (id >= 0) && ((id - ECNL::ENOD_REMOTE_ID) < @enodadrb_table.length)");
295 sb.AppendLine(" end");
296 }
297 sb.AppendLine();
298 if (!funcs.Contains("get_local_addr")) {
299 sb.AppendLine(" def get_local_addr()");
300 sb.AppendLine(" TargetBoard::get_local_addr()");
301 sb.AppendLine(" end");
302 }
303 sb.AppendLine();
304 if (!funcs.Contains("get_multicast_addr")) {
305 sb.AppendLine(" def get_multicast_addr()");
306 sb.AppendLine(" TargetBoard::get_multicast_addr()");
307 sb.AppendLine(" end");
308 }
309 sb.AppendLine();
310 if (!funcs.Contains("get_remote_addr")) {
311 sb.AppendLine(" def get_remote_addr(id)");
312 sb.AppendLine(" index = id - ECNL::ENOD_REMOTE_ID");
313 sb.AppendLine(" if (index < 0) || (index >= @enodadrb_table.length)");
314 sb.AppendLine(" nil");
315 sb.AppendLine(" else");
316 sb.AppendLine(" @enodadrb_table[index]");
317 sb.AppendLine(" end");
318 sb.AppendLine(" end");
319 }
320 sb.AppendLine();
321 if (!funcs.Contains("get_remote_id")) {
322 sb.AppendLine(" # 通信レイヤーアドレスの同じものを検索");
323 sb.AppendLine(" def get_remote_id(ep)");
324 sb.AppendLine(" id = ECNL::ENOD_REMOTE_ID - 1");
325 sb.AppendLine(" for ea in @enodadrb_table do");
326 sb.AppendLine(" id += 1");
327 sb.AppendLine(" if !ea then");
328 sb.AppendLine(" next");
329 sb.AppendLine(" end");
330 sb.AppendLine(" if !TargetBoard::equals_addr(ea, ep) then");
331 sb.AppendLine(" next");
332 sb.AppendLine(" end");
333 sb.AppendLine();
334 sb.AppendLine(" return id");
335 sb.AppendLine(" end");
336 sb.AppendLine();
337 sb.AppendLine(" return ECNL::ENOD_NOT_MATCH_ID");
338 sb.AppendLine(" end");
339 }
340 sb.AppendLine();
341 if (!funcs.Contains("set_remote_addr")) {
342 sb.AppendLine(" # 対応するリモートノードを検索");
343 sb.AppendLine(" def set_remote_addr(edata, ep)");
344 sb.AppendLine(" id = ECNL::ENOD_REMOTE_ID - 1");
345 sb.AppendLine(" for ea in @enodadrb_table do");
346 sb.AppendLine(" id += 1");
347 sb.AppendLine(" if !ea then");
348 sb.AppendLine(" next");
349 sb.AppendLine(" end");
350 sb.AppendLine(" if !is_match(svc, edata, ep) then");
351 sb.AppendLine(" next");
352 sb.AppendLine(" end");
353 sb.AppendLine();
354 sb.AppendLine(" # 対応するリモートノードがあれば通信レイヤーアドレスを設定");
355 sb.AppendLine(" @enodadrb_table[id - ECNL::ENOD_REMOTE_ID] = ep");
356 sb.AppendLine();
357 sb.AppendLine(" return id");
358 sb.AppendLine(" end");
359 sb.AppendLine();
360 sb.AppendLine(" return ECNL::ENOD_NOT_MATCH_ID");
361 sb.AppendLine(" end");
362 }
363 sb.AppendLine();
364 if (!funcs.Contains("add_remote_addr")) {
365 sb.AppendLine(" # 空き領域を探して自動登録");
366 sb.AppendLine(" def add_remote_addr(edata, ep)");
367 sb.AppendLine(" id = ECNL::ENOD_REMOTE_ID - 1");
368 sb.AppendLine(" for ea in @enodadrb_table do");
369 sb.AppendLine(" id += 1");
370 sb.AppendLine(" if ea then");
371 sb.AppendLine(" next");
372 sb.AppendLine(" end");
373 sb.AppendLine();
374 sb.AppendLine(" @enodadrb_table[id - ECNL::ENOD_REMOTE_ID] = ep");
375 sb.AppendLine();
376 sb.AppendLine(" return id");
377 sb.AppendLine(" end");
378 sb.AppendLine();
379 sb.AppendLine(" if @enodadrb_table.length >= 100 then");
380 sb.AppendLine(" return ECNL::ENOD_NOT_MATCH_ID");
381 sb.AppendLine(" end");
382 sb.AppendLine();
383 sb.AppendLine(" id = @enodadrb_table.length;");
384 sb.AppendLine(" @enodadrb_table[id] = ep");
385 sb.AppendLine();
386 sb.AppendLine(" return id + ECNL::ENOD_REMOTE_ID");
387 sb.AppendLine(" end");
388 sb.AppendLine("end");
389
390 code = sb.ToString();
391 }
392 return code;
393 }
394
395 string itr_code()
396 {
397 var sb = new StringBuilder();
398
399 sb.AppendLine("itr = esv.itr_ini()");
400 sb.AppendLine("itr.itr_nxt()");
401 sb.AppendLine("until itr.is_eof do");
402 sb.AppendLine(" if itr.epc == 0xD6 then");
403 sb.AppendLine(" # LEDをON");
404 sb.AppendLine(" digitalWrite(2, 1)");
405 sb.AppendLine(" end");
406 sb.AppendLine(" itr.itr_nxt()");
407 sb.AppendLine("end");
408
409 return sb.ToString();
410 }
411 }
412}
Note: See TracBrowser for help on using the repository browser.