World: r3wp
[Core] Discuss core issues
older newer | first last |
Graham 15-Aug-2010 [17833x2] | I did actually try copying the functions but they still operated on the original windows and not the new ones ... :( |
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. |
older newer | first last |