[Bf-taskforce25] context/operator changes

vekoon vekoon at gmail.com
Thu Mar 19 01:26:18 CET 2009


Maybe I'm missing something but I'll try to express my opinion anyway 
(it'll be long and boring, sorry).

As stated in the design documents for the new operator system the idea 
was that Context + Operator creates an Action, but that doesn't 
necessarily mean this is the only way to achieve the Action.
In fact from my point of view it was exactly the opposite, i.e. it was 
the answer to the question "How could we achieve an Action which is 
data-independent (so that it's reusable)?" and the answer was Context, 
because context is an abstract representation of state-dependent data. 
Meaning we could actually translate the above equation to (Data * State) 
+ Operator = Action. Ok it's not meant to be mathematically accurate, 
just to explain.

The reason Context is used (and thought of) in an atomic way is that as 
I said State is an abstract concept, you can't really manipulate it by 
itself but it represents the current State in which the Data is and in 
which the Action should be executed in. It's like the environment for 
the action. So by keeping the Action dependent on the State, because at 
any given time you always know what the current State is, you have a way 
to keep both separated and to repeat the same Action under different 
State conditions. This was the main reason for having State-dependent 
Data in the first place.

On the other hand, as much as it's true the above statement, it's also 
true that Data + Function = Action. In this case the State is ignored 
which means the Action is directly binded to the Data. This is perfectly 
fine when you have some direct Data you want to act upon which by 
consequence means you can only repeat the Action when having access to 
that specific Data.

Now by giving access only to State-dependent data you're actually 
forcing a State change every time you want to act upon some Data, i.e. 
select objects A and B and then move selected objects. This is a big 
limitation in many real-world circumstances.
For people who programmed in Win32 or windows in general this is already 
obvious by considering the limitations a control like RichEdit forces 
upon the developer for which you actually have to first mark the 
selection you want to act upon (text of course in this case) and then 
invoke the command you'd like to apply (i.e. Make Bold) and which 
reflects how you act on it as a user.
This is the reason why other types of more complex piece of software 
like firefox, internet explorer itself and other browsers in general had 
to adopt a DOM centered way of manipulating data (those in web 
development are perfectly aware of this).
This does not mean they dropped Context-based interactivity (which in 
their case just means Selection-based). The latter indeed allows those 
softwares to generalize an idea of Command (which really resembles the 
idea of Tool-Operator in the end) which acts on current Context, can be 
automatically described, associated with custom keystrokes, 
undone/redone or could even be macroed although they didn't implement 
macros as they were really of no use in their case.

My "Blender API" proposal actually tried to provide this. It would not 
be code duplication in that the idea would be to create a generic API 
function like "move object" and then reuse this in both the direct-data 
and operator API. Also with a well thought generic API and some minor 
changes to my BlenderAPI code we could actually automatize the creation 
of bridge functions between the BlenderAPI calling system and normal C 
one by generating the corresponding C functions within the makesapi 
module which mostly consists of parameters creation/conversion and 
should be easy to do.
I don't really see how this lower level interaction would be a problem 
or how this even is low level for that matter. You can't have a good 
level of extensibility if you can't access the data you want where you 
want and act directly upon it. Other advanced programs do this and yes 
this adds complications, but avoiding the problem is not a solution 
especially if it means limiting the functionality a lot.

Not to be rough or anything but to me what "context decoupling" really 
looks like is a nicer way of calling an hack to a system that was good 
for its purpose in order to make it fit into something it is not suited 
for, attaching lot of added complexity to it.
My idea is simple: when a py script is run it can get current Context, 
i.e. the Context the script was run into. From context it can pull out 
the context-dependent stuff it needs (like selected objects) or use the 
Context directly to call Operators but because operators are just high 
level wrappers around a generic API it really wouldn't need to unless he 
wants those commands to be macroed for instance. This way you have a 
dynamic system, highly functional and extensible; you make operators a 
lot simpler (removing the need of context decoupling) and you let devs 
take care of the full potential and the problems this potential may cause.

On a final note (also to kinda strengthen my point) look at Firefox and 
all the problems it has: badly documented and full-of-issues APIs, huge 
memory usage, complex trickeries to get more advanced stuff working. And 
yet it's eating up on market share on every other browser (especially 
IE). This is because its add-ons are extremely powerful yet relatively 
easy to write, and that's the key. Users search for good functionality, 
devs for simplicity so you have to combine both elements in order to 
"succeed", even if this means not having a perfect design, which is 
impossible to get anyway.
Probably I should have avoided this final note as it's mostly irrelevant 
but my point is that a complex "low level" API is always needed for a 
complex application, you can't avoid it. Otherwise you end up creating 
various APIs for various purposes because you find you need something 
for custom GUIs, so you create UI templates, then maybe skinning, so you 
create UI styles; then you'll surely need a way to create and manage 
screen layouts and there's another differently custom API. Then custom 
toolbars buttons creation, then menus, then custom editors, then what? 
You end up with tons of different custom APIs for doing all the 
different things you need to be able to do which in the end will look 
exactly like having a single "low level" API but it'll be subdivided and 
inconsistent.

Ok, this mail is already getting too long. For whoever actually got to 
read up to the end, good job. Of course I'm perfectly open to any 
argument against a more generic "low level" API and how all the other 
elements that need extensibility and customization could or would be 
dealt with in that case.


Brecht Van Lommel wrote, on 18/03/2009 19.17:
> Hi all,
>
> I'm working on context/operator changes discussed at Wintercamp, mostly
> with the purpose of improving python interaction.
>
> Check this diagram:
> http://wiki.blender.org/index.php/Image:Operator_control_flow2.5.png
> And example code:
> http://pasteall.org/4607/c
>
> The basic idea is sound I think, but I'm running into some consequences
> and questions while implementing this, so I'm looking for feedback. See
> the XXX marked comments in the code, and the notes below.
>
> properties vs. context
> ----------------------
>
> When all context data is passed along as properties, it becomes tedious,
> not only for the operator code but also for python scripts having to
> specify these things over and over. For me it's not clear where to draw
> the line. Some examples:
>
> * Does delete objects get scene as a property?
> * Does grab in mesh editmode get the selection mode (vertex/edge/face)
> as a property?
> * Does set 3d cursor get the 3d view space as a property?
>
> in/out RNA
> ----------
>
> As can be seen in the example code, the operator type and operator now
> have separate in and out properties. I prefer this over one RNA struct
> with properties tagged for input/output.
>
> poll
> ----
>
> The poll() callback now only should run when the operator is used as a
> tool. This means exec/invoke have to do more verification, since python
> may pass in an object that is not in editmode for example, while poll()
> would guarantee this otherwise.
>
> poll/input/output names
> -----------------------
>
> I've called the get_context/set_context callbacks input()/output(). The
> names of these callbacks, and actually poll() is a bit unclear. Longer
> names like user_input/user_output/user_poll or
> context_input/context_output/context_poll may be better, but are a bit
> long?
>
> context RNA
> -----------
>
> Context now works with RNA pointers, to get things accessible by python.
> However some things currently in the context are not RNA wrapped, like
> Base or EditBone. Do we want this dependency of context on RNA, and
> assume things will get RNA wrapped in the future, or do we want some
> sort of support for putting stuff in the context that is not RNA
> wrapped? They could be passed as UnknownType, but that's not so nice.
>
> context global/localization
> ---------------------------
>
> Currently there are CTX_data_* functions in BKE_context, which look a
> lot like globals. In a way they should be global, to permit decoupling
> operators from spaces, but I'm not really comfortable with the way it is
> now. It's not clear at all what is available when.
>
> I'm changing the context lookups to be based on strings, so that they
> become extensible by python. This permits to get rid of these CTX_data_*
> functions, but it means what is in the context is effectively
> undocumented, and you might get a pointer of a type you did not expect.
>
> Not sure what to do here. Is there a good system to localize and
> document this context stuff better? One approach would be to make the
> input() callback do more, but then operators again get strongly coupled
> to the spaces. Or define context RNA and associated CTX_data_* functions
> per module, but it's unclear where that fits.
>
>
> Brecht.
>
>
>
> _______________________________________________
> Bf-taskforce25 mailing list
> Bf-taskforce25 at blender.org
> http://lists.blender.org/mailman/listinfo/bf-taskforce25
>
>   


More information about the Bf-taskforce25 mailing list