GithubHelp home page GithubHelp logo

richorama / ironblock Goto Github PK

View Code? Open in Web Editor NEW
77.0 13.0 22.0 19.65 MB

:arrow_forward: A .net core interpreter for blockly programs

Home Page: https://richorama.github.io/IronBlock/

License: MIT License

C# 62.90% HTML 3.11% JavaScript 33.98%
blockly netcore

ironblock's Introduction

ASP.NET Core CI

IronBlock

A .net core interpreter for blockly, allowing you to execute blockly programs in .NET.

Installation

Via nuget:

PM> Install-Package IronBlock

or

> dotnet add package IronBlock

Basic Usage

Firstly, in JavaScript save your blockly workspace as an XML file:

var xml = Blockly.Xml.workspaceToDom(workspace);

The blockly code demo allows you to view the XML of your workspace.

The XML will look something like this:

<xml>
  <block type="text_print">
    <value name="TEXT">
      <shadow type="text">
        <field name="TEXT">Hello World</field>
      </shadow>
    </value>
  </block>
</xml>

You'll need to pass this XML to your .NET server using an Ajax call or similar.

You can then parse the XML, and execute the Blockly program in .NET.

using IronBlock;
using IronBlock.Blocks;

// create a parser
var parser = new Parser();

// add the standard blocks to the parser
parser.AddStandardBlocks();

// parse the xml file to create a workspace
var workspace = parser.Parse(xml);

// run the workspace
var output = workspace.Evaluate();

// "Hello World"

// you can optionally pass in a dictionary of variables
var args = new Dictionary<string,object>();
args.Add("message", "Hello!");
workspace.Evaluate(args);

// if your program sets any variable values,
// you can read then out of the args dictionary 

Custom Blocks

Blockly has a block designer allowing you to create your own blocks very easily.

Custom blocks can be implemented in C# by inheriting IBlock:

public class MyCustomBlock : IBlock
{
    public override object Evaluate(Context context)
    {
        // read a field
        var myField = this.Fields.Get("MY_FIELD");
        
        // evaluate a value
        var myValue = this.Values.Evaluate("MY_VALUE", context);
        
        // evaluate a statement
        var myStatement = this.Statements.Get("MY_STATEMENT");
        myStatement.Evaluate(context); // evaluate your statement

        // if your block returns a value, simply `return myValue`

        // if your block is part of a statment, and another block runs after it, call
        base.Evaluate(context);
        return null;
    }
}

You can then register your block and run it:

var parser = new Parser();
parser.AddBlock<MyCustomBlock>("my_custom_block");
var workspace = parser.Parse(xml);
workspace.Evaluate();

License

MIT

ironblock's People

Contributors

adefwebserver avatar aiv-wizata avatar deyrajiv avatar imackintosh avatar richorama avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ironblock's Issues

Stop executing evaluation

Hi man,
first of all: thank you for this awesome library!
Now, considering that I will run long tasks with blocks (minimum half a minute), I'd like to implement a mechanism to cancel the current execution. How can I do?

Run/Step/Pause/Resume

Add ability to Run/Step/Pause/Resume at block granularity

depends on #36 #37

  • possibly use ManualResetEvent as mechanism to pause/resume
  • possibly use AutoResetEvent for step
  • can the base EventWaitHandle be used for both?

Whitespace

Hi
I'm using the Blockly ListsSplit block to do a Join using a space as a delimiter. However, the space representing the delimiter is getting removed.
In my XML one of my fields comes through from blockly like: <field name="TEXT"> </field>
Note the space as the field value is still present.
The problem appears to be with xdoc.LoadXml(xml) Because xdoc.PreserveWhitespace = false which then automatically removes any whitespace.
I was wondering if your Parse() method could be changed in Parser.cs to be:

        public Workspace Parse(string xml, bool preserveWhitespace = false)
        {
            var xdoc = new XmlDocument();
            xdoc.PreserveWhitespace = preserveWhitespace;
            xdoc.LoadXml(xml);

Thanks
Ivan

Problem with getting field value from custom block

I have folowing XML:

<xml xmlns="https://developers.google.com/blockly/xml">
  <block type="math_arithmetic" id="|A4ulz@A}mGUo0h3pZR|" x="244" y="356">
    <field name="OP">ADD</field>
    <value name="A">
      <block type="ParamBlock" id="aFD-Tf.=);AUrQC^qIOy">
        <field name="PARAM_INDEX">0</field>
        <value name="LIST">
          <block type="ParamListBlock" id="4:q.0!x,?(K!S7@b|{+h">
            <field name="DEBUG_VALUE">0</field>
          </block>
        </value>
      </block>
    </value>
    <value name="B">
      <block type="ParamBlock" id="tZ%.6rM?c^ig`Wa[~cdo">
        <field name="PARAM_INDEX">1</field>
        <value name="LIST">
          <block type="ParamListBlock" id="NmsQHLb{Mb=?6duWrbR;">
            <field name="DEBUG_VALUE">0</field>
          </block>
        </value>
      </block>
    </value>
  </block>
</xml>

Here is the Custom block:

public class ParamBlock: IBlock
  {
    public override object Evaluate(Context context)
    {
      // read a field
      var index= this.Fields.Get("PARAM_INDEX");

      // evaluate a value
      var list= this.Values.Evaluate("LIST", context);

     return list[index];
    }
  }

I added my CustomBlock with

var block = new ParamBlock();
parser.AddBlock("ParamBlock", block);

During debugging of the code the debugger run for two times in the method "Evaluate". So for so good.

  • The property "Id" is always "tZ%.6rM?c^ig`Wa[~cdo".
  • The Property "Fields" contains always the fields of both blocks.
  • The property "Values" contains always the values of both blocks.

In my opinion it has to be:

  • each block instance has his own id.
  • each block contains only the field and values for himself.

I am a little bit confused. ;-)

Remove C# codegen

Does anyone use the codegen? I was thinking of bumping to 2.0.0 and removing it.

Missing output tag

Inside IBlock interfacce implementation it's missing the output tag information, it's a mistake or there Is a reason ?

Dynamic type

Hello i'm using your project to generate a linq espression, but i founded a problem with Dynamic type.The idea it's to add a parameter to parser to skip variabile declaration and to declarare it at first assignament, May i do this change and commit It ?

Block type "math_change" missing

The block "math_change" is missing inside AddStandardBlocks().

image

I got error message that block type "math_change" is not registered.

updated nugets?

I noticed you have changes on the main branch but your nugets are much older. Any plan to release a new verison?

Help with WebAPI to Blockly

Hello ,
I have created another component with Blockly:

It takes WebAPI ( + swagger + OData ) specification and transforms to Blockly blocks with Javascript. For an example, see https://netcoreblockly.herokuapp.com/blockly.html .

I think that your project can be usefull to execute also on the backend , not just to the frontend.

For this, I need some help about how to implement

TypeArgumentBase - this is the value
ActionInfo - this is the function ( WebAPI , ODATA, and so on)

( To understand ,you could start from

  var strDef = GenerateDefinitionString(type);
            var strJS = GenerateJSstring(type);


it will be helpfull if it will have a GenerateC# or similar

Waiting for your answer

Update Microsoft.CodeAnalysis.CSharp.Scripting version

Depended lib Microsoft.CodeAnalysis.CSharp.Scripting was updated, was deleted Microsoft.CodeAnalysis.IMessageSerializeble interface
dotnet/roslyn#25360
Trying to use IronBlock from Azure Function and see the error:
System.Private.CoreLib: Exception while executing function: Function1. IronBlock: Could not load type 'Microsoft.CodeAnalysis.IMessageSerializable' from assembly 'Microsoft.CodeAnalysis, Version=3.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'

Signed assembly

Would it be possible to get a signed assembly so it can easily be used in other signed assemblies?

Json support?

Looking at the blockly site and links for creating blockly blocks etc you provide they all generate json now not XML. I assume everything converted over to json from XML so i there a plan to support json in your library?

Before/AfterBlock hooks

In order to visualise/log the running script it would be handy to have before/after hooks .

  • Add Before After hooks to Block model (those will apply to specific block)
  • Add Before After hooks to Context model (those will apply to every block)
  • Before/After method should have access to Context

Hook Implementation:

  • Option one: use nullable Func variables or delegates reference in models, easy to check for null and execute if not null

  • Option two: Use EventHandlers and delegates

    • Should be fastest method? widely used for time sensitive events lime mouse interaction
    • build in handling of empty handler
  • Option three: Add Before/After abstract method to base block and context models, let implementation override it.

    • waste of resources if hooks are not used as the abstract method would always be called
    • Possible to use interfaces IBeforeAction, IAfterAction, implemented interfaces can be detected, still I imagine simple null check is faster.

Differences between Generate and Evaluate

@richorama Hi Richard, I had bit more time and started to look at the implementation of the tickets I put some time ago.
One thing I notice there is Generate is creating subContext for block operations like "if", "while" or "procedure call".
Is there reason why Evaluate is not doing it?

Comments for code generation

Is there a chance that you can include the blockly comments as "real" comments in code generation (for evaluation this is not needed).

Currently I'm using a custom comment block containing a text input field. During code creation I then create an empty statement with a comment trivia containing the text from the input field which is then set as trailing trivia on the empty statement.

This works, but the generated code looks a bit unconventional with every comment starting with a semicolon.

Btw.: Thanks for keeping the code generation alive ;)

Infinite nested NEXT on finite sequence

Hi, I am having an issue with the following XML:

image

https://gist.github.com/justinvvitale/1e2e476b4d5624b306ab0b1cd4f361d6

It appears in Blockly as such:
image

However the parser interprets it as the following:

image

It appears to loop indefinitely.

Am I missing something or is this a bug.

An unrelated question I have is why do my waitblocks share the same fields but have a different ID ( shouldn't they be a new object?). I think I am doing something wrong, a way around this would be to clear the fields after consuming them but this doesn't seem right.

image

Thanks

New Features (execution interrupt, Before After hooks)

Hi Richard,
I am planning to use the IronBlocks in my app, I need to add some features:

  • Separate thread executor
  • improve hierarchical context (hierarchical variable evaluation)
  • interrupt/resume/step execution (at block granularity)
  • fixed rate execution (blocks/per minute - mainly for visualisation)
  • execution logging/visualisation (Before/After block hooks - mainly to highlight the current block in Blockly)

Would you be interesting in collaboration/pulling the changes in?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.