r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Core] Discuss core issues

Graham
15-Aug-2010
[17834]
I got it all working using Gregg's suggestion .. but I'm open to 
others
Anton
15-Aug-2010
[17835x3]
Well, here's the modified code.
hello: does [f/text: copy "hello" show f]

bind-funcs: func [word] [

 foreach window-function [hello][bind second get window-function word]
]

open-window: does [
	view/new center-face layout vid-context [
		f: field

  button "Hello" [bind-funcs 'f hello] ;  Pass to BIND-FUNCS any one 
  of the words in this context (here 'f).
		button "Clear" [clear-face f]
	]
]

open-window
open-window
do-events
It's not brilliant; in each button action you have to call bind-funcs 
before calling any of the window functions (eg. hello).
Graham
15-Aug-2010
[17838]
which is what I am doing at present .. binding before calling the 
function
Anton
15-Aug-2010
[17839]
Yeah, so I've just made it more complex than necessary.
Graham
15-Aug-2010
[17840x2]
now if the functions could access the 'self of the object, it could 
bind automatically?
just rewrite every function ...
Anton
15-Aug-2010
[17842]
It's the same problem; how could the functions know which object 
to bind to?
Graham
15-Aug-2010
[17843x2]
so I would pass the context to each function as a parameter
so these would be self aware functions :)
Anton
15-Aug-2010
[17845]
Usually I just write functions and pass the face(s) that they need 
to work on. Passing the context could cut down the number of arguments 
passed to one. But usually I don't need to pass more than one face, 
so it doesn't seem of that much benefit.
Graham
15-Aug-2010
[17846x3]
So, rewrite the function to take a parameter word from the context 
it is to work in, and let it bind itself to that context ...
well, I have named fields ... and a bunch of data coming in which 
I need to fill the fields
either I fill by position, or by name
Anton
15-Aug-2010
[17849]
You can bind directly to a context now, you don't need to pass an 
example word, unless you are using a very old rebol version...
Graham
15-Aug-2010
[17850]
anonymous contexts ??
Anton
15-Aug-2010
[17851x6]
Alright, well, if you have a function which manipulates many faces, 
then there are arguments to be cut down, and there is a benefit.
Anonymous, yes.
ctx: context [a: 1]
bind [a] ctx
You no longer have to do:
bind [a] in ctx 'self
or
bind [a] in ctx 'a
Ok, so you can rewrite each of your window functions to take, and 
bind itself to, a context argument; or, you can add a "BIND-FUNCS" 
function, taking a context argument, which rebinds all your window 
functions to the context.
Similar to what I've done above.
So, each function binds itself:
hello: func [ctx] [do bind [f/text: copy "hello" show f] ctx]

open-window: does [
	view/new center-face layout vid-context [
		f: field

  button "Hello" [hello self] ;  Pass to HELLO this context (created 
  by VID-CONTEXT).
		button "Clear" [clear-face f]
	]
]

open-window
open-window
do-events
Graham
15-Aug-2010
[17857]
yes ...
Anton
15-Aug-2010
[17858]
Or, all the functions are rebinded by BIND-FUNCS:
Graham
15-Aug-2010
[17859]
That might be the easier way .. .to get the binding be handled by 
the function itself
Anton
15-Aug-2010
[17860x2]
hello: does [f/text: copy "hello" show f]

bind-funcs: func [ctx] [

 foreach window-function [hello][bind second get window-function ctx]
]

open-window: does [
	view/new center-face layout vid-context [
		f: field

  button "Hello" [bind-funcs self hello] ;  Pass to HELLO this context 
  (created by VID-CONTEXT).
		button "Clear" [clear-face f]
	]
]

open-window
open-window
do-events
(Oops - the comment should be ; Pass to BIND-FUNCS ...
Graham
15-Aug-2010
[17862]
you don't like the idea of the function itself doing the binding?
Anton
15-Aug-2010
[17863x6]
If you don't like the idea of modifying all your functions, then 
it might be more convenient. Also, you might call bind-funcs just 
once, then call several of your functions afterwards without having 
to pass them anything.
(Note, all this tricky function rebinding makes the functions non-reentrant.)
Another idea I have is to patch your styles (eg. BUTTON, FIELD etc.) 
so that when their action blocks are converted to functions, the 
blocks are bound to the right context.
You can see here the block: function

print mold get in svv/vid-styles/button 'multi
...
block: func [face blk][
        if pick blk 1 [
            face/action: func [face value] pick blk 1

            if pick blk 2 [face/alt-action: func [face value] pick blk 2]
        ]
    ]


It has all it needs to determine the context returned by VID-CONTEXT.
From the FACE argument (eg. the newly created BUTTON face), you can 
climb up to the window face, then search through its subfaces for 
one with a word VAR facet. That word should have been already bound 
by VID-CONTEXT, so that means we can pre-bind the action block to 
the context (just before the action function is created from it).
You would just need to modify the multi/block function for each of 
the styles which converts block to action functions.
Graham
15-Aug-2010
[17869x2]
why does re-entrance matter?
we don't have multitasking in R2
Anton
15-Aug-2010
[17871x2]
Actually, it looks like the multi/block function is the same for 
all styles.
If you want to port your code later, it might be significant. If 
not, don't worry.
Maxim
15-Aug-2010
[17873]
binding control in R3 is one of my favorite things that got a major 
boost in capability.
Anton
16-Aug-2010
[17874x3]
Here's a proof of concept for that idea I mentioned:
svv/vid-styles/button/multi/block: func [face blk][ ; <- This only 
does BUTTON for now.
	if pick blk 1 [
		;face/action: func [face value] pick blk 1

  face/action: func [face value /local window word] compose/only [

   window: face/parent-face ; Find the window face <-- (simplistic for 
   now)

   word: window/pane/1/var ; Find a word which references a field in 
   the window. <-- (simplistic for now)
			print "Remake action function."

   face/action: func [face value] probe append append copy [bind-funcs] 
   to-lit-word word (pick blk 1)
			do-face face value
		]

  if pick blk 2 [face/alt-action: func [face value] pick blk 2] ; <- 
  Also need to remake alt-action similarly to action, above.
	]
]
bind-funcs: func [word] [

 foreach window-function [hello][bind second get window-function word]
]

hello: does [f/text: copy "hello" show f]

open-window: does [
	view/new center-face layout ctx: vid-context [
		f: field
		button "Hello" [hello]
		button "Clear" [clear-face f]
	]
]

open-window
open-window
do-events
That was fun to figure out, but I'm not sure it's worth all the extra 
complication yet. Would have to see if it is straightforward and 
consistent to use, or makes things too confusing to understand later. 
It would definitely need some good docs.
Graham
16-Aug-2010
[17877]
so when you use the action of a button, it binds the context of the 
first word in the action block to the current context
Anton
16-Aug-2010
[17878]
Not the first word in the action block, no.
Graham
16-Aug-2010
[17879x3]
So, what side effects are there ?
if the action is to update a different window in a different context 
.. I guess that action would stop working ....
and it doesn't solve the issue where the function you are rebinding 
actually calls a different function to update the gui
Anton
16-Aug-2010
[17882]
The major side-effect is that the action of each face (eg. button, 
field) will remake itself the first time it is used, to insert a 
snippet of code to rebind the window funcs before your specified 
action code uses them.
Graham
16-Aug-2010
[17883]
So, I suspect it is better to allow the programmer to select the 
context instead of automating it.