Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Would there be any interest in my upstreaming this?

43 views
Skip to first unread message

Alan Smith

unread,
Jan 8, 2025, 11:25:58 AMJan 8
to Blockly
For my own project, I have created a change notifier where blocks can register a callback method to be called upon certain block change events on a certain block type.

(This was because several of my onChange events had filters in them and I figured it would be easier to have one filtering mechanism that dispatched events.)

I don't know whether this is just useful for my use case or would be more generally useful so I thought I would check here to see if there is any interest in my upstreaming it.

It won't hurt my feelings if the answer is - we are glad this helps you, but have thought about it and it doesn't belong in Blockly proper.

Thanks,

Alan

Christopher Allen

unread,
Jan 8, 2025, 1:23:29 PMJan 8
to blo...@googlegroups.com
Hi Alan,

For my own project, I have created a change notifier where blocks can register a callback method to be called upon certain block change events on a certain block type.

(This was because several of my onChange events had filters in them and I figured it would be easier to have one filtering mechanism that dispatched events.)

This is very interesting, and I would definitely be interested in seeing your design doc (if you have one) as well as further information about the problem you are solving with it.

I'm not sure we would necessarily be interested in upstreaming your changes, but it sounds like they are at least adjacent to an existing known issue in Blockly, specifically that there are some situations where the library blocks use onchange handlers to try to enforce program validity, but because they can only do so after-the-fact this can cause problems such as breaking undo.  I would at some point like to replace onchange handers with another more synchronous mechanism; even if your code doesn't address this directly it would be good for us to understand your needs, since ideally Blockly would have a single recommended way of doing such change listening that deals with both situations.  (We'll probably retain onchange listeners for legacy reasons, but there were already a number of reasons why they are not a great mechanism.)

So yes, please: 
  • Tell us more about the problem you were trying to solve.
  • Share any design docs you have, if you are able to.
  • Feel free also to share code if you like, but note that we are unlikely to want to upstream it as written unless it also solves the issues described in the issue linked above.

Best wishes,

Christopher

Alan Smith

unread,
Jan 10, 2025, 10:57:14 AMJan 10
to blo...@googlegroups.com
I don't have a design doc as my first version was a simplistic solution to solve my specific problem.   Some details:

I am working on the next-gen Blocks code for FIRST.  (On the new control system, we'll be expanding Blocks programming for FTC (FIRST Tech Challenge) and also making it available for FRC (FIRST Robotics Challenge).   These are for middle and high school students.)

Since our libraries are very object oriented, I am adding object oriented functionality to Blocks.   (I am trying very diligently to not modify Blocks and instead use it as a library.  So far I have been successful.).    This involves having classes, methods, class variables and local variables.     

(I am starting where you can have multiple classes in a workspace.  For pedagogical reasons, we may change to only one class per workspace where the workspace only shows the methods.   But we'll probably leave that until we are further along and test it with various students and educators.)

When you add a method to a class (right now it is an input), I look at block_move for the class_method block and when "reason" is "connect", I rename if necessary to keep it unique.
I do a similar things when you add parameters to a method, or create a class variable, or create a local variable. 

I have to do it when they are added to a class (or method for local variable), instead of in a validator because it might be valid in one class and not in another.

So that means I had multiple places that had onChange methods that did very similar things filtering on the change event type and the block type.    I could see that this might grow in the future, so I made a very simple change Framework so that I wouldn't have multiple pieces of code doing all the filtering.

Here is the code I have right now (this is under an MIT license).  I know it is overly simplistic, but I share it so you can see how limited functionality I am actually using.   I am new to typescript (and Javascript) so if I am doing something dumb, I would appreciate it being pointed out as a better way I could do it.

Thanks,

Alan  

import * as Blockly from 'blockly';

// The purpose of this is to allow blocks to register for changes only of their type and the events they care about
// warning - only one change listener per block type is allowed. a second one will overwrite it.

type CallbackFunctionBlockType = (block: Blockly.Block, blockEvent : Blockly.Events.BlockBase) => void;

let registeredCallbacks = new Map<string, [string[], CallbackFunctionBlockType]>;

let blockEvents = [Blockly.Events.BLOCK_CHANGE, Blockly.Events.BLOCK_CREATE, Blockly.Events.BLOCK_DELETE, Blockly.Events.BLOCK_MOVE];

export function registerCallback(blockType : string, blockEvents : string[], func : CallbackFunctionBlockType){
registeredCallbacks.set(blockType, [blockEvents, func]);
}

function changeListener(e: Blockly.Events.Abstract){
if (blockEvents.includes(e.type as any)){
let eventBlockBase = (e as Blockly.Events.BlockBase);
let workspace = Blockly.Workspace.getById(eventBlockBase.workspaceId!)
let block = workspace?.getBlockById(eventBlockBase.blockId!)!
if(!block){
return;
}
let callbackInfo = registeredCallbacks.get(block.type);
if(!callbackInfo){
return;
}
if(callbackInfo[0].includes(e.type)){
callbackInfo[1](block, eventBlockBase);
}
}
}

export const setup = function (workspace: Blockly.Workspace) {
workspace.addChangeListener(changeListener);
}


--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/blockly/CAN0w5eZOvkJVMQrHMw%3DitS1rEnQQ%2BWtYDXMPR2-n--MZA1ni6Q%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages