My model consists of a family tree of objects all of which have an xhtml ruled cell. The client needs to be updated if the value of this slot has changed. However, a change in one would cascade up the tree so if we were logging these changes, and sending them down to the client, one of the things we send would be the entire document which is not what we want.
How do I set up the observer to log the change only if it has not been accounted for already.
Andy,
I don't get what you want to achieve...
Am 28.03.2008 um 14:17 schrieb Andy Chambers:
My model consists of a family tree of objects all of which have an xhtml ruled cell. The client needs to be updated if the value of this slot has changed. However, a change in one would cascade up the tree so if we were logging these changes, and sending them down to the client, one of the things we send would be the entire document which is not what we want.
How do I set up the observer to log the change only if it has not been accounted for already.
Is it:
A kid's observer is firing due to a change but that change should not be reaching the client because the parent's observer's firing is enough for the (web) client to react to? If so, you could suppress the sending of a web client update when *parent* is bound and is not nil (this is meant to mean: I have a parent, so I am a kid. As a kid I don't need to update the client).
???
Frank
On Fri, Mar 28, 2008 at 2:49 PM, Frank Goenninger frgo@mac.com wrote:
Andy,
I don't get what you want to achieve...
Am 28.03.2008 um 14:17 schrieb Andy Chambers:
My model consists of a family tree of objects all of which have an xhtml ruled cell. The client needs to be updated if the value of this slot has changed. However, a change in one would cascade up the tree so if we were logging these changes, and sending them down to the client, one of the things we send would be the entire document which is not what we want.
How do I set up the observer to log the change only if it has not been accounted for already.
Is it:
A kid's observer is firing due to a change but that change should not be reaching the client because the parent's observer's firing is enough for the (web) client to react to? If so, you could suppress the sending of a web client update when *parent* is bound and is not nil (this is meant to mean: I have a parent, so I am a kid. As a kid I don't need to update the client).
No its the other way around. I don't want to have to send the whole page if its just a little bit of text that's changed. There's a javascript library called jquery that allows you to say things like...
$("#my-id").html("Hello World");
Translated, that means find the html element with id "my-id" and set the html inside it to be "Hello World". If I can just keep track of all the little changes, I'll send a list of these commands to be eval'd on the client.
-- Andy
Andy Chambers wrote:
On Fri, Mar 28, 2008 at 2:49 PM, Frank Goenninger frgo@mac.com wrote:
Andy,
I don't get what you want to achieve...
Am 28.03.2008 um 14:17 schrieb Andy Chambers:
My model consists of a family tree of objects all of which have an
xhtml ruled cell. The client needs to be updated if the value of this slot has changed. However, a change in one would cascade up the tree so if we were logging these changes, and sending them down to the client, one of the things we send would be the entire document which is not what we want.
How do I set up the observer to log the change only if it has not been accounted for already.
Is it:
A kid's observer is firing due to a change but that change should not be reaching the client because the parent's observer's firing is enough for the (web) client to react to? If so, you could suppress the sending of a web client update when *parent* is bound and is not nil (this is meant to mean: I have a parent, so I am a kid. As a kid I don't need to update the client).
No its the other way around. I don't want to have to send the whole page if its just a little bit of text that's changed. There's a javascript library called jquery that allows you to say things like...
$("#my-id").html("Hello World");
Translated, that means find the html element with id "my-id" and set the html inside it to be "Hello World". If I can just keep track of all the little changes, I'll send a list of these commands to be eval'd on the client.
Coolio. I am about to send something with the OpenGL version to help with some ideas.
Question: Can you feed #my-id to the browser and then reference it later in a page send? Or must it originally arrive as part of a larger X/HTML tree, only after which it can be referred to directly?
kt
Frank Goenninger wrote:
Andy,
I don't get what you want to achieve...
Am 28.03.2008 um 14:17 schrieb Andy Chambers:
My model consists of a family tree of objects all of which have an xhtml ruled cell. The client needs to be updated if the value of this slot has changed. However, a change in one would cascade up the tree so if we were logging these changes, and sending them down to the client, one of the things we send would be the entire document which is not what we want.
How do I set up the observer to log the change only if it has not been accounted for already.
Is it:
A kid's observer is firing due to a change but that change should not be reaching the client because the parent's observer's firing is enough for the (web) client to react to? If so, you could suppress the sending of a web client update when *parent* is bound and is not nil (this is meant to mean: I have a parent, so I am a kid. As a kid I don't need to update the client).
???
This is an interesting case where we can get some efficiency where the engine we are driving allows it. DHTML lets us change a specific node in the DOM without resending a whole page, OpenGL lets us rebuild a display list and have it take effect whenever any larger display list calls it:
(defmd ogl-node () (dsp-list (c-formula (:lazy :until-asked) (without-c-dependency (map nil 'dsp-list (kids self))) (let ((display-list-name (or .cache (gl-gen-lists 1)))) ; #1 ;---start building this list ----- (gl-new-list display-list-name gl_compile) (ix-paint self) (gl-end-list) ;---end building (setf (redisplayp .og.) t) ; Note #2 display-list-name))) ;; always the same once allocated
#1 display-list-name (actually just an integer) is like an OpenGL object ID. When larger structures render, they render kids by "calling" the kids' display lists by these names. gl-call-list or something.
#2 notice that this rule mutates the display list, it does not allocate a new one. (The whole scheme breaks down if we do that.) So we will forever be returning the same "name" and so the Cells engine will not see any change. Observers will not run and (crucially) users will not get invalidated. This is way cool because this is exactly what we want. The only dependencies arise during that call you see to IX-PAINT. If I reference any other cell and that changes, then when the name slot gets sampled Cells will kick off the rule to rebuild the list.
When do they get sampled? I think the display callback runs down the visual hierarchy sampling each node's list to get it rebuilt before runnning down it again to actually render -- you cannot build a display list and render at the same time.
So it is both a little awkward yet strangely Cells-friendly.
kt
I should have added more notes:
This is an interesting case where we can get some efficiency where the engine we are driving allows it. DHTML lets us change a specific node in the DOM without resending a whole page, OpenGL lets us rebuild a display list and have it take effect whenever any larger display list calls it:
(defmd ogl-node () (dsp-list (c-formula (:lazy :until-asked)
"lazy" to start because we cannot build a display list until the opengl context gets established. Eager thereafter because (I was wrong, we do not need to artificially sample each list on each display call to get the invalid lists rebuilt) we want propagation of any releavnt change to kick off the rule to get the display list rebuilt.
(without-c-dependency (map nil 'dsp-list (kids self)))
Here I am getting kids ready before I myself build my list: an OpenGL list can recursively /call/ other lists, but we can /build/ recursively, so I sample all my kids before building. I do it without-dependency because this is the issue Andy raised: a sub-node changing does not mean we need to resend the parent node.
(let ((display-list-name (or .cache (gl-gen-lists 1)))) ; #1 ;---start building this list ----- (gl-new-list display-list-name gl_compile) (ix-paint self) (gl-end-list) ;---end building (setf (redisplayp .og.) t) ; Note #2
I forgot to explain that normally we would have an observer on the slot trigger the redisplay, but these slots do not change in value, they mutate the display list definition on the OpenGL side, so we have to trigger the redisplay differently. And this is just a bit of global state that needs to get set /someplace/, no harm if a hundred lists say "redisplay!".
kt
display-list-name))) ;; always the same once allocated
#1 display-list-name (actually just an integer) is like an OpenGL object ID. When larger structures render, they render kids by "calling" the kids' display lists by these names. gl-call-list or something.
#2 notice that this rule mutates the display list, it does not allocate a new one. (The whole scheme breaks down if we do that.) So we will forever be returning the same "name" and so the Cells engine will not see any change. Observers will not run and (crucially) users will not get invalidated. This is way cool because this is exactly what we want. The only dependencies arise during that call you see to IX-PAINT. If I reference any other cell and that changes, then when the name slot gets sampled Cells will kick off the rule to rebuild the list.
When do they get sampled? I think the display callback runs down the visual hierarchy sampling each node's list to get it rebuilt before runnning down it again to actually render -- you cannot build a display list and render at the same time.
So it is both a little awkward yet strangely Cells-friendly.
kt
cells-devel site list cells-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/cells-devel
haha! Nice exchange, it persuaded me (along with FG's report a while back of success) to re-enable display lists, so far (touch wood) it Just Works!
Not that things were slow without them... hmm, maybe I better check and make sure they are not... nope... but still, should make things even zippier.
I have been thinking about it, it sounds as if we can treat Ajax like OpenGL so we have a leg up on the implementation.
kt