Blockly uygulamaları genellikle çıkış dili olarak JavaScript oluşturur. Bu, genellikle bir web sayfasında (muhtemelen aynı veya yerleştirilmiş bir WebView) çalıştırılmak için yapılır. Her oluşturucuda olduğu gibi ilk adım, JavaScript oluşturucuyu eklemektir.
import {javascriptGenerator} from 'blockly/javascript';
Çalışma alanından JavaScript oluşturmak için şu işlevi çağırın:
javascriptGenerator.addReservedWords('code');
var code = javascriptGenerator.workspaceToCode(workspace);
Elde edilen kod doğrudan hedef web sayfasında yürütülebilir:
try {
eval(code);
} catch (e) {
alert(e);
}
Yukarıdaki snippet, temel olarak kodu oluşturup değerlendirir. Ancak birkaç noktayı daha açıklamak isteriz. Bir iyileştirme, eval'in try
/catch
içine sarmalanmasıdır. Böylece, çalışma zamanındaki hatalar sessizce başarısız olmak yerine görünür olur. Bir diğer iyileştirme de code
'in ayrılmış kelimeler listesine eklenmesidir. Böylece, kullanıcının kodu bu ada sahip bir değişken içeriyorsa çakışma yerine otomatik olarak yeniden adlandırılır. Tüm yerel değişkenler bu şekilde ayrılmalıdır.
Öne Çıkan An Blokları
Kod çalıştırıldığında, o anda yürütülmekte olan bloğun vurgulanması kullanıcıların programlarının davranışını anlamalarına yardımcı olur. JavaScript kodu oluşturulmadan önce STATEMENT_PREFIX
ayarlanarak vurgulama ifade düzeyinde yapılabilir:
javascriptGenerator.STATEMENT_PREFIX = 'highlightBlock(%1);\n';
javascriptGenerator.addReservedWords('highlightBlock');
Çalışma alanındaki bloğu işaretlemek için highlightBlock
değerini tanımlayın.
function highlightBlock(id) {
workspace.highlightBlock(id);
}
Bu işlem sonucunda her ifadenin önüne highlightBlock('123');
ifadesi eklenir. Burada 123
, vurgulanmak istenen bloğun seri numarasıdır.
Sonsuz Döngüler
Elde edilen kodun her zaman söz dizimi açısından doğru olduğu garanti edilse de sonsuz döngüler içerebilir. Durdurma sorununu çözmek Blockly'nin kapsamı dışında olduğundan bu tür durumlarda en iyi yaklaşım, bir sayaç tutmak ve her iterasyonda sayacı azaltmaktır.
Bunu yapmak için javascriptGenerator.INFINITE_LOOP_TRAP
değerini, her döngüye ve her işleve eklenecek bir kod snippet'i olarak ayarlayın. Aşağıda bir örnek verilmiştir:
window.LoopTrap = 1000;
javascriptGenerator.INFINITE_LOOP_TRAP = 'if(--window.LoopTrap == 0) throw "Infinite loop.";\n';
var code = javascriptGenerator.workspaceToCode(workspace);
Örnek
JavaScript oluşturma ve yürütmeyle ilgili canlı bir demo aşağıda verilmiştir.
JS-Interpreter
Kullanıcının bloklarını düzgün bir şekilde çalıştırmak istiyorsanız JS-Interpreter projesi sizin için idealdir. Bu proje, Blockly'den ayrıdır ancak Blockly için özel olarak yazılmıştır.
- Kodu istediğiniz hızda çalıştırın.
- Yürütmeyi duraklatma/devam ettirme/adım adım yürütme.
- Bloklar yürütülürken bunları vurgulama.
- Tarayıcının JavaScript'inden tamamen izoledir.
Çevirmeni çalıştırma
Öncelikle JS-Interpreter'ı GitHub'dan indirin:
Ardından kodu sayfanıza ekleyin:
<script src="acorn_interpreter.js"></script>
Bu işlevi çağırmanın en basit yolu, JavaScript'i oluşturmak, yorumlayıcıyı oluşturmak ve kodu çalıştırmaktır:
var code = javascriptGenerator.workspaceToCode(workspace);
var myInterpreter = new Interpreter(code);
myInterpreter.run();
Çevirmen modunu kullanma
Kodu daha yavaş veya daha kontrollü bir şekilde yürütmek için run
çağrısını, adım atan bir döngüyle (bu durumda 10 ms'de bir adım) değiştirin:
function nextStep() {
if (myInterpreter.step()) {
setTimeout(nextStep, 10);
}
}
nextStep();
Her adımın bir satır veya blok değil, JavaScript'te son derece ayrıntılı olabilecek bir anlamsal birim olduğunu unutmayın.
API ekleme
JS-Interpreter, tarayıcıdan tamamen izole edilmiş bir korumalı alandır. Dış dünyayla işlem yapan tüm bloklar için yorumlayıcıya bir API eklenmelidir. Tam açıklama için JS-Interpreter belgelerine bakın. Ancak öncelikle uyarı ve istem bloklarını desteklemek için gereken API'yi burada bulabilirsiniz:
function initApi(interpreter, globalObject) {
// Add an API function for the alert() block.
var wrapper = function(text) {
return alert(arguments.length ? text : '');
};
interpreter.setProperty(globalObject, 'alert',
interpreter.createNativeFunction(wrapper));
// Add an API function for the prompt() block.
wrapper = function(text) {
return prompt(text);
};
interpreter.setProperty(globalObject, 'prompt',
interpreter.createNativeFunction(wrapper));
}
Ardından, yorumlayıcı başlatma işleminizi initApi işlevini iletecek şekilde değiştirin:
var myInterpreter = new Interpreter(code, initApi);
Uyarı ve istem blokları, varsayılan blok grubunda yorumcu için özel API gerektiren tek iki bloktur.
highlightBlock()
bağlanıyor
JS-Interpreter'da çalışırken highlightBlock()
, kullanıcı programda ilerledikçe korumalı alan dışında hemen yürütülmelidir. Bunu yapmak için işlev bağımsız değişkenini yakalayacak bir sarmalayıcı işlevi highlightBlock()
oluşturun ve bunu yerel işlev olarak kaydedin.
function initApi(interpreter, globalObject) {
// Add an API function for highlighting blocks.
var wrapper = function(id) {
return workspace.highlightBlock(id);
};
interpreter.setProperty(globalObject, 'highlightBlock',
interpreter.createNativeFunction(wrapper));
}
Daha gelişmiş uygulamalar, bir öne çıkarma komutuna ulaşılana kadar duraklatma olmadan adımları tekrar tekrar yürütmek ve ardından duraklamak isteyebilir. Bu strateji, satır satır yürütmeyi simüle eder. Aşağıdaki örnekte bu yaklaşım kullanılmaktadır.
JS-Interpreter Örneği
JavaScript'i adım adım yorumlamanın canlı bir demosunu aşağıda bulabilirsiniz. Bu demo, diğer asenkron davranışlar (ör. konuşma veya ses, kullanıcı girişi) için kullanılabilecek iyi bir örnek olan bir bekleme bloğu içerir.