[Laszlo-dev] API change proposal: <node>/destroy behavior, when destroying child nodes recursively
André Bargull
andre.bargull at udo.edu
Tue Jan 27 11:52:54 PST 2009
On 1/27/2009 4:47 PM, P T Withington wrote:
> On 2009-01-27, at 09:46EST, André Bargull wrote:
>
>>
>> On 1/27/2009 1:03 AM, P T Withington wrote:
>>> On 2009-01-26, at 18:24EST, André Bargull wrote:
>>>> Oh wait, you just said nothing in the LFC depends on the current way
>>>> things work. I really believed in you,
>>> But wait, I said:
>>> "where a child node _needs_ to access it's parent when the parent is
>>> in the process of being deleted"
>>> so, there may be cases where it _does_ access the parent, but does it
>>> _need_ to? I don't think it does. So it is just a matter of fixing
>>> those cases to be careful.
>>
>> How do you plan to find those cases?
>
> One way would be to set parent to null and then fix the bugs it reveals.
It'd be great to have JS2 getters in this case. So you can generate a
debugger warning in one release and by that give people the chance to
update their sources. And in a next release, you'd apply the real
proposed change. That way user applications continue to work.
Like:
---
private var _parent:LzNode;
public function get parent () :LzNode {
if ($debug) {
if (_parent.__LZdeleted) {
Debug.warn("danger");
}
}
// return parent but give a warning when parent is already destroyed
return this._parent;
}
---
>
>> For example what is going to happen for constraints? The example [2]
>> isn't a real-life example (it makes no sense to do anything like
>> that), but through replication [1] and other means, you can end up
>> destroying the parent-node and then it's really difficult to find the
>> source of possible runtime errors.
>
> This is exactly what led me down this path. I was looking at
> replication in nav.lzx and realized that it was making hundreds of
> useless operations because as each child was destroyed, it told the
> parent to update its layout, which caused the parent to adjust the
> position of each child (even though that child would be destroyed soon).
>
Adding the same if-condition to "__LZresolveReferences" as in
"__LZapplyArgs" ('bail if deleted'), presumedly helps to reduce some
useless operations when applying constraints to destroyed nodes..
> Doesn't this just indicate a bug in the interaction of replication and
> the focus manager? My take is that you are updating your dataset, so
> the replicator destroys and re-allocates nodes to represent the updated
> dataset, but the focusmanager is still hanging on to the destroyed node.
When the new data-node is added, replication just starts to run. It's
more about pooling, but see below.
> Either the focus manager needs to store its state in terms of "dom
> position" (i.e., a path to the node that has focus, rather than a
> reference to the actual node), or the replication manager has to
> cooperate with the focus manager to tell it when it has replaced the
> node that has focus.
>
> Why does it work for lazy replication? Because the lazy replicator is
> much more careful not to destroy a node that maps to a data element that
> is still in the range when it is updated -- it leaves those nodes in
> place. This would be one way to fix the bug for normal replication, and
> it would presumably make it more efficient too!
Almost right: in normal replication (without pooling!), the initial node
is destroyed. But in lazy replication, pooling is automatically enabled,
so the initial node is not destroyed and therefore no runtime exception
is generated.
And the bug is not caused by the replication-manager, it's a bug in
LzView. The view must check in its destroy method the current focus and
if necessary clear focus.
(I just used that replication example because I know how replication
works, so it's easily possible for me to force runtime exceptions under
certain conditions.)
More information about the Laszlo-dev
mailing list