[Glade-devel] Property Binding: Fixing the big blocker



On Mon, Nov 21, 2011 at 1:04 PM, Denis Washington <denisw at online.de> wrote:
Am 18.11.2011 19:49, schrieb Tristan Van Berkom:

On Fri, Nov 18, 2011 at 2:24 AM, Denis Washington<denisw at online.de>
?wrote:

Am 15.11.2011 22:44, schrieb Tristan Van Berkom:

I think that it's obvious the mechanism is needed, but I dont think that
we
should clear bindings based on sensitivity state, in other words I would
much
rather that sensitivity always be the last thing which is evaluated
based
on other real states (it doesnt seem to make sense that we drive a
'real'
project state based on the 'virtual' sensitivity state, and I fear with
the
complexity of Glade that that will bite us later on).

So, for the scenario you described above, functionally speaking I
think this needs
to happen:

? o Button editor sets the edit mode and does glade_command_push_group()
? o Button editor does it's normal command group routines
? o Button editor invalidates the "label" property (note: this
invalidation does not exist)
? o Invalidating the "label" property causes bindings to that label to
become invalid, in
? ? ?fact anything which "refers to that property" is invalid, today
this can only be a binding
? ? ?of another property.
? ? ? o A widget has a property which was bound to the "label"
property which was invalidated,
? ? ? ? ?as a consequence of that action, it's binding to the said
label is undoably cleared
? ? ? o GladeWidgetAdaptor->evaluate_sensitivity ( use_command = TRUE
) is called on
? ? ? ? ?that target property's widget to re-evaluate sensitivity
states after having changed
? ? ? ? ?the binding state
? o All widgets with any binding to the invalidated label finish
adjusting themselves to the
? ? ?invalidation
? o Button editor calls GladeWidgetAdaptor->evaluate_sensitivity (
use_command = TRUE )
? ? ?on itself to evaluate the sensitivity after having changed it's
own "edit mode"
? o Finally glade_command_pop_group() is hit

The "invalidation" above might be a signal from the source
GladeProperty which has
a strict meaning, or possibly just a function
glade_command_property_invalidate()
which loops over all the targets, unsets them and resolves the
sensitivity of the
target widget.

I am not sure how the additional "invalidation" command you envision
would
conceptually differ from glade_command_set_sensitive (sensitive = FALSE).
While I understand your intention, the fact that the property sensitivity
*does* affect the binding state still remains in your proposed design; it
is

And enter the confusion:

? ?a.) Bindings use this virtual state of 'sensitivity' to clear
themselves
? ?b.) Anything else... like activatable properties, looks at the code you
? ? ? ? wrote and decides that it's also a good idea to clear itself when
it
? ? ? ? something goes insensitive
? ?c.) Code competes for real states because of insignificant
sensitivity changes

Yes, it is important that when one editor sets a property insensitive,
the binding
updates/clears itself, however it is also important that that clearing
is not simply
*because* of the sensitivity state.

OK, I think I know where you're getting at now. You want to ensure that the
binding removal only happens if a property is made sensitive because it is
invalidated by an Editor, not because of any other random kinds of property
sensitivity changes. Seen this way, a separate "invalidation" command is
surely a superior design.


At any rate, if you were to drive the project states from the sensitivity
state,
you would still need to find a way to do it undoably while the sensitivity
is
set as a command.

i.e. it's important that:

? a.) Editor sets activatable stuff that makes a property insensitive
? b.) Property undoably goes insensitive
? c.) Binding is undoably unset

a, b and c have to happen as part of the same command group (so you
cant very well listen to a sensitivity changed signal and clear the
binding state).

just indirected by the "invalidate" command. Also, the "invalidation"
logic
in the Editor would inevitably duplicate the logic in
GladeWidgetAdaptor->evaluate_property_flags() (or
->evaluate_sensitivity(),
we we're going to call it), meaning that changes to that logic alway
requires modifications to two places (error-prone). In short, I think
this
needlessly complicates things without benefit.

For reference, this is how the process works currently in the
"command-set-sensitive" branch:

1. The Editor does glade_command_group_push() and does what it has always
done.

2. Editor calls "GladeWidgetAdaptor->adjust_property_flags (use_command =
TRUE)". That function's implementation uses
glade_command_set_property_sensitive(), which checks whether any bindings
become invalidated by the sensitivity change and, in turn, calls
"glade_command_bind_property (binding_target, NULL)" as needed (grouped
with
the original sensitivity-setting command).

Right, so in this specific step we have code that explicitly writes out
that if
you set a property insensitive... *only* bindings are effected, which
singles
out bindings as some kind of a special case feature.

This is where a generalized "clear property" with a general meaning would
be better.

Actually, I agree with this now. A separate notion of invalidation is much
clearer and less fragile. Given that, we might even be able to omit
glade_command_set_property_sensitive() and call
GladeWidgetAdaptor->evaluate_sensitivity() from the invalidation command
instead.

Yes that's kindof what I had in mind, ideally the source and target evaluate
the sensitivity using the adaptor method in as most cases as possible (hopefully
all cases).

The other detail about the 'clear property' or 'invalidate property' semantics
is not entirely clear to me, I suppose one approach would be to fire a signal
on a GladeProperty when it is supposed to be cleared.

For instance...

  o the activatable editor goes ahead and clears
     a property which is actually a binding source (somewhere inside
     the command group which it declares)... possibly by calling
         glade_property_clear (property, use_command = TRUE);

  o Then the "clear" or "invalidate" signal is fired on the said GladeProperty
     with a 'use-command' parameter as TRUE

  o GladeProperty code would implicitly connect to the "invalidate" signal
     on it's set 'source property', when the property is cleared then the source
     property attribute can be unset undoably

  o Some specific GladeWidgets will be allowed to connect to an "invalidate"
     signal on a property of another GladeWidget, if ever more code is developed
     which needs to do an action at property invalidation time, this can be done
     by listening to this signal and without adding custom code to
glade-command.c


Historically you need to know that all the worst code ends up in
glade-command.c
because we are too lazy to do things properly, then we add adaptor methods
to
do things more generically and pull hard-code out of glade-command.c...
I'm just
trying to avoid that.

So you're thinking of something like GladeWidgetAdaptor->invalidate()? How
would that be better than simply having glade_command_invalidate_property()?
I cannot think of any way thank specific widget types would need different
implementations of this.

No no, I was just trying to illustrate how particularly fragile the
"Controller"
element of Glade's MVC model is (or can potentially get, when trying to
handle things using a procedural approach from glade-command.c, which
is always the most obvious approach ... but has drawbacks).

And... thanks a lot for your patience with this.




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]