This is a read-only archive of the old Scratch 1.x Forums.
Try searching the current Scratch discussion forums.

#1 2010-12-24 14:13:28

rubiks_cube_guy238
Scratcher
Registered: 2009-07-02
Posts: 100+

Special form reporter blocks

I just found out that you can add a new block like this:

Code:

('nameOfBlock' #rs #blockCode)

and you can make a special-form reporter block. This means that the code should be executed in the ScratchProcess. However, it appears to be that a little tweaking has to be done in order for this to work. Can anyone look into this a little bit?


The glass is never half full nor half empty; it is twice as large as it needs to be.

Offline

 

#2 2010-12-24 15:01:01

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Special form reporter blocks

Let me have a look, im not promising. nXIII could help more - but I haven't heard from him recently.


You can now reach me on Twitter @johnnydean1_

Offline

 

#3 2010-12-25 05:30:53

TheSuccessor
Scratcher
Registered: 2010-04-23
Posts: 1000+

Re: Special form reporter blocks

I got this to work once... I'll dig out my code now. Even though it's Christmas Day.


/* No comment */

Offline

 

#4 2010-12-25 06:05:25

TheSuccessor
Scratcher
Registered: 2010-04-23
Posts: 1000+

Re: Special form reporter blocks

I couldn't find my experimental code, so I quickly wrote this. IT IS UNTESTED. Hopefullly it will work. To return the value to the block from the method in ScratchProcess, use returnValueToParentFrame:.
Add this to ReporterBlockMorph:

Code:

showValue: msg

    | tmsg tooltip w worldBounds |
    tmsg _ msg.
    (self isBooleanReporter or: [msg = 'Error!']) ifTrue: [
        tmsg _ msg localized].
    tooltip _ (ScratchReporterToolTipMorph string: tmsg for: self)
        left: self right;
        bottom: self top.
    ScratchTranslator isRTL ifTrue: [tooltip right: self left].
    (msg = 'Error!') ifTrue: [tooltip messageColor: Color red darker].

    w _ self world.
    w addMorphFront: tooltip.
    ((worldBounds _ w bounds) containsRect: tooltip bounds) ifFalse:
        [tooltip bounds: (tooltip bounds translatedToBeWithin: worldBounds)].

    self setProperty: #toolTip toValue: tooltip.
    tooltip initialCursorPoint: Sensor cursorPoint.
    tooltip startStepping.

Add an instance variable to ReporterBlockMorph called returnValue.

Add this method as well:

Code:

returnValue: aValue
    returnValue _ aValue.

Replace toggleProcess with this:

Code:

toggleProcess

    | toolTip |
    toolTip _ self valueOfProperty: #toolTip.
    toolTip ifNotNil: [
        toolTip delete.
        self setProperty: #toolTip toValue: nil.
        ^ self].

    self isSpecialForm ifTrue: [super toggleProcess. self showValue: returnValue] ifFalse: [self showValue].

In ScratchProcess, replace returnValueToParentFrame with this:

Code:

returnValueToParentFrame: anObject
    "Append the given object to the argument list of my parent frame."

    | f b |
    stackFrame ifNil: [^ self].
    f _ stackFrame parentFrame.
    [f notNil and: [f shouldUnlight]] whileTrue: [
        f _ f parentFrame].
    f ifNil: [b _ stackFrame expression. (b isKindOf: ReporterBlockMorph) ifTrue: [b returnValue: anObject]] ifNotNil: [f addArgument: anObject].

Hope it works  smile


/* No comment */

Offline

 

#5 2010-12-27 11:54:05

TheSuccessor
Scratcher
Registered: 2010-04-23
Posts: 1000+

Re: Special form reporter blocks

Bump


/* No comment */

Offline

 

#6 2010-12-27 18:40:21

zorket
Scratcher
Registered: 2010-05-25
Posts: 500+

Re: Special form reporter blocks

Yeah, BYOB has a special form reporter called The script. Guessed blockspec: ('the script %z' #rs #theScript)
This probably is the wrong blockspec, because I don't have BYOB.
The users LS97, nxiii, TheSuccessor, and zorket probably can figure out the mystery.


Marzipan11 must learn to not spoil

Offline

 

#7 2010-12-27 21:22:45

rubiks_cube_guy238
Scratcher
Registered: 2009-07-02
Posts: 100+

Re: Special form reporter blocks

zorket wrote:

Yeah, BYOB has a special form reporter called The script. Guessed blockspec: ('the script %z' #rs #theScript)
This probably is the wrong blockspec, because I don't have BYOB.
The users LS97, nxiii, TheSuccessor, and zorket probably can figure out the mystery.

Believe it or not, that block actually has 2 commandSpecs.
They are:

Code:

('the script' #q #procedure)

and

Code:

('the script. Input names: %s' #q #procedureWithArgs)

.
The first commandSpec is the block you see in the palette, but it actually turns into an entirely new block (but with the same nested script) when you press the little arrow on the side.

And, actually, the block is not evaluated in the ScratchProcess.
You can find the evaluation method hidden under the codename 'optimized'  tongue

Code:

optimized
    | newBlock reportBlock sel body a rcv |

    rcv _ self receiver.
    rcv ifNil: [rcv _ ScriptableScratchMorph new].
    (#(function #autoBlock) includes: selector)
        ifTrue: [sel _ #procedure]
        ifFalse: [sel _ #procedureWithArgs].
    newBlock _ rcv blockFromSpec: (rcv wholeBlockSpecForSelector: sel) 
                            color: (ScriptableScratchMorph blockColorFor: 'operators').

    newBlock isAtomic: (isAtomic or: [self isKindOf: OSlotMorph]).

    reportBlock _ rcv blockFromSpec: (rcv wholeBlockSpecForSelector: #doAnswer) 
                            color: (ScriptableScratchMorph blockColorFor: 'control').

    body _ self body.
    body ifNotNil:[
        reportBlock replaceArgMorph: (reportBlock argMorphs first) by: body].

    2 to: argMorphs size - 1 do: [:i |
        newBlock addItem ].

    2 to: argMorphs size do: [:i |
        a _ (argMorphs at: i) fullCopy.
        newBlock replaceArgMorph: (newBlock argMorphs at: i - 1) by: a ].

    newBlock attachBlock: reportBlock.
    newBlock parameters: parameters.
    newBlock variables: variables.
    newBlock fixInitialFrame.
    ^newBlock

(although I doubt that will make any sense to anyone except Jens or bharvey)


The glass is never half full nor half empty; it is twice as large as it needs to be.

Offline

 

#8 2010-12-28 12:17:06

rubiks_cube_guy238
Scratcher
Registered: 2009-07-02
Posts: 100+

Re: Special form reporter blocks

To make a special-form reporter block, all you have to do is make an exception in CommandBlockMorph evaluate.
Example: Let's say I wanted to make a boolean block that reports if the nested reporter block will cause an error when evaluated. To do this, we go to CommandBlockMorph evaluate, as I mentioned above, and change it to

Code:

evaluate
    selector = #willRaiseError:
        ifTrue: 
            [[(self argumentAt: 1) evaluate]
                ifError: [^ true].
            ^ false].
    ^ self evaluateWithArgs: self args

The glass is never half full nor half empty; it is twice as large as it needs to be.

Offline

 

#9 2010-12-29 05:30:06

TheSuccessor
Scratcher
Registered: 2010-04-23
Posts: 1000+

Re: Special form reporter blocks

Did my method work?


/* No comment */

Offline

 

#10 2010-12-29 09:35:47

rubiks_cube_guy238
Scratcher
Registered: 2009-07-02
Posts: 100+

Re: Special form reporter blocks

Um, No. (Scratch froze. It's a good thing I didn't save before testing it.)
And if you had read my last post, you would have seen that I had found a way to make reporter blocks act as special forms.

Last edited by rubiks_cube_guy238 (2010-12-29 09:37:11)


The glass is never half full nor half empty; it is twice as large as it needs to be.

Offline

 

Board footer