2013年6月9日日曜日

Blockly+linda.jsなこと(linda-arduino-sensorの値をとるコードを作成してみた)

(ブロックの表記は'温度計の値を読む'とかにして,内部でjsコードが正しくできあがるって方向に進めると良さげなんだろう.たぶん)
Result:



How:
配置
1. blockly(-read-only)
svn checkout http://blockly.googlecode.com/svn/trunk/ blockly-read-only
2. jquery.min.js
3. index.html (based on blockly-read-only/demos/generator/index.html)
'rpi.local'はlinda-baseが動いているマシン
<html>
    <head>
  <meta charset="utf-8">
  <title>blocky - linda</title>
  <script type="text/javascript" src="blockly-read-only/blockly_compressed.js"></script>
  <script type="text/javascript" src="blockly-read-only/en_compressed.js"></script>
  <script type="text/javascript" src="blockly-read-only/javascript_compressed.js"></script>


  <script type="text/javascript" src="./language_linda.js"></script>
  <script type="text/javascript" src="./language_utility.js"></script>
  <script src="./jquery.min.js"></script>
  <script src="http://rpi.local:5000/rocketio/linda.js"></script>
  <script>
   var linda= new Linda();
  </script>


  <style>
   body {
    background-color: white;
    font-family: sans-serif;
   }
   h1 {
    font-weight: normal;
    font-size: 140%;
   }
  </style>
 </head>
 <body>
  <p>
   <button onclick="showCode()">
    Show JavaScript
   </button>
   <button onclick="runCode()">
    Run JavaScript
   </button>
  </p>

  <div id="blocklyDiv" style="height: 480px; width: 600px;"></div>

  <xml id="toolbox" style="display: none">
   <category name="Control">
    <block type="controls_if"></block>
    <block type="controls_repeat_ext">
     <value name="TIMES">
      <block type="math_number">
       <title name="NUM">10</title>
      </block>
     </value>
    </block>
    <block type="controls_whileUntil"></block>
   </category>
   <category name="Logic">
    <block type="logic_compare"></block>
    <block type="logic_operation"></block>
    <block type="logic_negate"></block>
    <block type="logic_boolean"></block>
   </category>
   <category name="Math">
    <block type="math_number"></block>
    <block type="math_arithmetic"></block>
    <block type="math_single"></block>
   </category>
   <category name="Text">
    <block type="text"></block>
    <block type="text_length"></block>
    <block type="text_print"></block>
   </category>

   <category name="Variables" custom="VARIABLE"></category>
   <category name="List">
    <block type="lists_create_empty"></block>
    <block type="lists_create_with"></block>
    <block type="lists_repeat">
     <value name="NUM">
      <block type="math_number">
       <title name="NUM">5</title>
      </block>
     </value>
    </block>
    <block type="lists_length"></block>
    <block type="lists_isEmpty"></block>
    <block type="lists_indexOf">
     <value name="VALUE">
      <block type="variables_get">
       <title name="VAR">list</title>
      </block>
     </value>
    </block>
    <block type="lists_getIndex">
     <value name="VALUE">
      <block type="variables_get">
       <title name="VAR">list</title>
      </block>
     </value>
    </block>
    <block type="lists_setIndex">
     <value name="LIST">
      <block type="variables_get">
       <title name="VAR">list</title>
      </block>
     </value>
    </block>
    <block type="lists_getSublist">
     <value name="LIST">
      <block type="variables_get">
       <title name="VAR">list</title>
      </block>
     </value>
    </block>
   </category>
   <category name="Linda">
    <block type="linda_createTupleSpace">
     <value name="TupleSpace">
      <block type="text">
       <title name="TEXT">myhome</title>
      </block>
     </value>
    </block>
    <block type="linda_watch">
     <title name="LIST">tuple</title>
    </block>
   </category>
   <category name="Utility">
    <block type="utility_log"></block>
   </category>

  </xml>

  <script>
   Blockly.inject(document.getElementById('blocklyDiv'), {
    path: 'blockly-read-only/',
    toolbox: document.getElementById('toolbox')
   });

   function showCode() {
    // Generate JavaScript code and display it.
    Blockly.JavaScript.INFINITE_LOOP_TRAP= null;
    var code= Blockly.Generator.workspaceToCode('JavaScript');
    alert(code);
   }

   function runCode() {
    // Generate JavaScript code and run it.
    window.LoopTrap= 1000;
    Blockly.JavaScript.INFINITE_LOOP_TRAP= 'if (--window.LoopTrap == 0) throw "Infinite loop.";\n';
    var code= Blockly.Generator.workspaceToCode('JavaScript');
    Blockly.JavaScript.INFINITE_LOOP_TRAP= null;
    try {
     eval(code);
    }
    catch (e) {
     alert(e);
    }
   }
  </script>

 </body>
</html>

4. language_linda.js
if(!Blockly.Language) {
    Blockly.Language= {};
}

Blockly.Language.linda_createTupleSpace= {
 category: 'Linda',
 helpUrl: '',
 init: function() {
  this.setColour(110);
  this.setOutput(true);
  this.appendValueInput('TupleSpace').appendTitle('Create TupleSpace:')
  this.setPreviousStatement(false);
  this.setNextStatement(false);
  this.setTooltip('Create a TupleSpace.');
 }
};

Blockly.Language.linda_watch= {
 category: 'Linda',
 helpUrl: '',
 init: function() {
  this.setColour(110);
  this.appendValueInput('TupleSpace').appendTitle('TupleSpace:');
  this.appendValueInput('Tuple').appendTitle('Watch Tuple:');
  this.appendDummyInput().appendTitle('Found Tuple:').appendTitle(new Blockly.FieldVariable(null), 'LIST');
  this.appendStatementInput('DO').appendTitle('Do');
  this.setPreviousStatement(true);
  this.setNextStatement(true);
  this.setTooltip('Watch the tuple in the tuplespace.');
 }
};

Blockly.JavaScript= Blockly.Generator.get('JavaScript');

Blockly.JavaScript.linda_createTupleSpace= function() {
 var _ts= Blockly.JavaScript.valueToCode(this, 'TupleSpace', Blockly.JavaScript.ORDER_NONE) || 'test';
 var code= "new linda.TupleSpace(" + _ts + ")"
 return [code, Blockly.JavaScript.ORDER_NONE];
};

Blockly.JavaScript.linda_watch= function() {
 var _ts= Blockly.JavaScript.valueToCode(this, 'TupleSpace', Blockly.JavaScript.ORDER_NONE) || 'ts';
 var _t= Blockly.JavaScript.valueToCode(this, 'Tuple', Blockly.JavaScript.ORDER_NONE) || '["sensor"]';
 var _l= Blockly.JavaScript.variableDB_.getName(this.getTitleValue('LIST'), Blockly.Variables.NAME_TYPE) || 'list';
 var branch= Blockly.JavaScript.statementToCode(this, 'DO');
 var code= _ts + ".watch(" + _t + ", function(" + _l + "){\n";
 code+= branch;
 code+= "\n});\n";
 return [code, Blockly.JavaScript.ORDER_NONE];
}; 
5. language_utility.js
if(!Blockly.Language) {
 Blockly.Language= {};
}

Blockly.Language.utility_log= {
 category: 'Linda',
 helpUrl: '',
 init: function() {
  this.setColour(111);
  this.appendValueInput('Message').appendTitle('console.log:');
  this.setPreviousStatement(true);
  this.setNextStatement(true);
  this.setTooltip('console.log()');
 }
};

Blockly.JavaScript= Blockly.Generator.get('JavaScript');

Blockly.JavaScript.utility_log= function() {
 var _msg= Blockly.JavaScript.valueToCode(this, 'Message', Blockly.JavaScript.ORDER_NONE) || '';
 var code= "console.log(" + _msg + ")"
 return code;
}; 

4 件のコメント:

shokai さんのコメント...

blocklyいいですね
今、linda-baseのWebUI上である程度プログラミングできるようにしようと思っています
というのは
1. センサ等のデータをtuplespaceに入れる
2. tuplespaceから読み取ってWebやマイコンに書き出す
というのはRubyなどで書いてそれぞれのデバイスで実行すればいいとして、
3. タプルを読んで簡単な計算をして、タプルを書き込む
というのを簡単にできるようにしたいなあと思ってます。

yahoo pipesみたいなのを作ればいいかと思いましたがblocklyもいいですね

shokai さんのコメント...

blocklyいいですね
今、linda-baseのWebUI上である程度プログラミングできるようにしようと思っています
というのは
1. センサ等のデータをtuplespaceに入れる
2. tuplespaceから読み取ってWebやマイコンに書き出す
というのはRubyなどで書いてそれぞれのデバイスで実行すればいいとして、
3. タプルを読んで簡単な計算をして、タプルを書き込む
というのを簡単にできるようにしたいなあと思ってます。

yahoo pipesみたいなのを作ればいいかと思いましたがblocklyもいいですね

shokai さんのコメント...

blocklyいいですね
今、linda-baseのWebUI上である程度プログラミングできるようにしようと思っています
というのは
1. センサ等のデータをtuplespaceに入れる
2. tuplespaceから読み取ってWebやマイコンに書き出す
というのはRubyなどで書いてそれぞれのデバイスで実行すればいいとして、
3. タプルを読んで簡単な計算をして、タプルを書き込む
というのを簡単にできるようにしたいなあと思ってます。

yahoo pipesみたいなのを作ればいいかと思いましたがblocklyもいいですね

p_g_ さんのコメント...


コメントありがとうございました.
また,日頃さまざまな媒体にて多くの情報を発信していただき,ありがとうございます.

linda-base上でのプログラミング機能というのは面白そうですね.
そのページをブラウズしているクライアントマシンがそのまま演算能力はもちろん,アイディアを提供できるわけですね.

今後もLindaの成長を楽しみにしています.