[Bf-taskforce25] RNA groups proposal, first alpha + patch

vekoon vekoon at gmail.com
Sat Feb 14 22:39:35 CET 2009


Hey guys,
The API refactor is more or less finished. This is a first *working* 
version of the entire implementation of RNA groups and everything that 
was depending on them and followed. This includes almost everything I 
suggested in my initial proposal with the exception of group filters 
which are only partially implemented and so disabled in this first 
release. I really wanted to include them already in this first patch but 
couldn't find the time but I decided to release this first alpha anyway 
so that there's at least some time span for people to try out before 
next sunday meeting (tomorrow) which I'm not sure I'll be able to attend 
but it's still relevant so there can be some discussion about the whole 
thing.

Now, keep in mind this is a _real_ alpha, meaning in the moment I 
finished it I created the patch so it could be instable in some 
circumstances and crash (for instance I think it could for objects with 
material nodes? not quite sure though). Also for the same reason there 
could be various glitches and misbehaviors and I already noticed there 
are maybe some leaks that I'll hack down later on.
The API modules themselves are pretty clean/polished (except some places 
where I recycled code from the old implementation that are not as clean) 
and although of course they're still in their alpha stage so they're 
surely not perfect I tried to make them workable and sane in term of 
readability. A part of the code that'll surely need to be checked is the 
readfile/writefile one which I'm not sure I did correctly and maybe I 
forgot something. Also some places because they were just demo code in 
the end I really didn't pay much attention so the code is not that nice 
especially in space_buttons where I left some unused code like 
buttons_selection, that was the selection region where it shows the 
selected objects: I didn't put that in as it was really irrelevant in 
terms of my proposal, you can put it in back if you want. Oh and I also 
noticed the area should be refreshed when the window is created but 
these are all very small tweaks I can think of later.

What we have now:
An API divided into 3 levels each of one depends on the levels it's 
preceded by. The first level is the group cache, accessible through 
editors/include/PG_cache.h and implemented in 
editors/interface/pg_cache. This is just a big object where all the 
groups are cached in relation to their properties so that groups -> 
subgroups -> properties type of access is highly optimized and lowers 
down the overhead of having groups as attributes for properties (which 
makes RNA api a lot easier to work with). This first level only depends 
on RNA which means the cache can be at the application level (which is 
the same as RNA's).
The second level is called group state. This maintains "state" 
information for every group you want it to, like collapsed state etc. 
and it's generally at the space level or deeper in the chain (and can be 
persisted on file so that this state information is kept). This is again 
dependent only on RNA but would probably be advisable to consider it 
dependent on group cache for future purposes.
The third and last level is group UI. This level is obviously targeted 
at generating automatic UI for groups. Various options include the idea 
of having also automatic layout where groups are displaced in an 
automatic way (this is optional though). As of now they get broken up in 
rows or columns at the height or width of the window (see code below). 
This level depends on both group cache and group state.
An example of how the API is used (taken from the space_buttons code):

------------------ CODE ----------------------

    gui= PG_ui_create(sbuts->gc, sbuts->gs);
    block= uiBeginBlock(C, ar, "buttons-block", UI_EMBOSS, UI_HELV);

    PG_ui_init(gui, C, ar);
    PG_ui_area_set(gui, 0, 0, winw, winh);

     if (winw >= winh+PG_ui_max_size_get(gui))
        PG_ui_flow_set(gui, PG_UI_FLOW_HOR);
    else
        PG_ui_flow_set(gui, PG_UI_FLOW_VER);

    PG_CACHE_BEGIN_ROOT(sbuts->gc, ritem)
    {
        group= PG_cache_group(sbuts->gc, ritem);
        if (RNA_grouprna_type(group)==GROUP_ROOT) {
            state= PG_state_item(sbuts->gs, group, 0);
            if (state && state->flag & PG_STATE_USE)
                if (buttons_data_for_group(C, group, &ptr))
                    PG_ui_draw_children(gui, ritem, &ptr, block);
        }
    }
    PG_CACHE_END

    uiEndBlock(C, block);
    uiDrawBlock(C, block);

    PG_ui_total_area_get(gui, NULL, NULL, &w, &h);

    /* update size of tot-rect (extents of data/viewable area) */
    if (PG_ui_flow_get(gui)==PG_UI_FLOW_HOR)
        UI_view2d_totRect_set(v2d, w?w:winw, winh);
    else
        UI_view2d_totRect_set(v2d, winw, h?h:winh);

    PG_ui_free(gui);

------------------ CODE ----------------------


Now to complete this e-mail I'd like to share my "vision" on how a 
possible final API could work. Note this is pseudo-code to make it 
easier to understand. All of this is actually already possible with my 
API although of course there are no py bindings for it.

group1 = rna.def_group('ObjectUserinfo', rna.Group_Object, GROUP_FLAGS, 
'User Info')
group2 = rna.def_group('ObjectUserinfoData', group1, GROUP_FLAGS, 
'Custom Data')

rna.def_prop('some_flag', 'bool', group=group1, ..., 'Some Flag');
rna.def_prop('some_name1', 'int', group=group2, ..., 'Some Name 1');
rna.def_prop('some_name2', 'int', group=group2, ..., 'Some Name 2');
rna.def_prop('some_name3', 'int', group=group2, ..., 'Some Name 3');

item = pg.cache_item(group2);
item.draw = draw_userinfo_data

def draw_userinfo_data( gui, item, stage, block, x, y, w, h):
    ...draw...
    #return this to skip default drawing for the group
    return pg.UI_STAGE_SKIP


And this is about it. I was thinking about making smaller patches but 
was too much time consuming so instead I made a single big patch. You 
can find it here: 
http://vekoon.googlecode.com/files/rna_groups_complete_0.1.patch
I tried it with scons/minngw and cmake/msvc8 and it worked fine, then I 
tried scons/msvc9 and it crashed but as of now I don't have time to 
check why this happens so I suggest you use one of the other methods 
(scons/mingw I'm pretty sure should work).
Try the code out and also have fun exporting some more groups like for 
materials etc. in rna_*.c files and see how it works out for you. In the 
moment you export some group they should automatically show up in the 
buttons window/properties editor (unless you set the group flag 
GROUP_INTERNAL) and under the correct context (not all contexts are 
handled yet though, like radiosity or sound). As I said there are 
probably still various glitches or weird things you'll see but this is 
mostly to get a feel on how it works and if it's actually usable and 
blend nicely in the workflow. Then of course, after winter camp, when 
all the new UI paradigms will be defined I'll rewrite the UI part of 
this code accordingly and later we'll think about ways of beautifying 
the display and drawing of groups.
I think it's all, impressions and comments are welcome.




More information about the Bf-taskforce25 mailing list