Hey list!

I've been trying to isolate the keyboard navigation as much as i could since 
you guys said it should be compiled optionally.

While a lot of stuff could be moved to it's own file (g_kbdnav.c) there are 
also a lot of code that need to be in the middle of pd's core functions.

For example, here is the modified canvas_obj() function on the g_text.c to not 
cinlude the code related to keyboard navigation:

https://gist.github.com/HenriAugusto/e417c8f269ad10df2dc3359b907ea588

It's not as pretty as it could be but it's readable (if your editor has code 
folding you can just hide the relevant lines to see what the code looks like, 
for example).

Is there a better way to do this?

Cheers,
Henri.
____________________________

Just in case, those are examples of some other modified core functions:

in g_text.c

glist_drawiofor(...) - draws a rectangle around the selected in/outlet
canvas_howputnew(...) - position a new object exactly below/above to selected 
in/outlet

in g_canvas.c

canvas_drawlines(...) - draws lines in different colors while navigating 
through connections
canvas_map(...) - draws each object's index if the user has asked so (useful 
for the goto functionality)


________________________________
De: Christof Ressi <[email protected]>
Enviado: terça-feira, 16 de julho de 2019 14:32
Para: Henri Augusto Bisognini <[email protected]>
Cc: [email protected] <[email protected]>
Assunto: Aw: Re: [PD-dev] First complete keyboard navigation prototype

Hi,

> But it appears that actually the size of the struct is deduced while 
> compiling. So if you write an external it is going to think the canvas struct 
> is the same size as it was in the pd header files that were used during 
> compilation.

exactly.

> When using the pointer to implementation idiom, wouldn't the pointer itself 
> change the size of the struct?

yes, it will

> You've said something about that not being a problem when you add it as the 
> last member of the struct but i don't understand why and how that would work.

usually, externals shouldn't care about the *size* the t_editor struct (at 
least I can't think of any use case), so you can get away with adding new 
fields at the end (although it's certainly not recommended). Note that those 
headers aren't really public anyway!

However, appending fields conditionally can lead to problems:

struct Foo {
    int a;
#ifdef FOO_EX
    int c;
#endif
};

Now let's say we need to add another member:

struct Foo {
    int a;
#ifdef FOO_EX
    int c;
#endif
    in b;
};

If the host compiles with FOO_EX defined and the client doesn't, the latter 
will assume a wrong offset for 'b'.

The solution is to add a field for private data *once*. The advantage is that 
a) we can hide the private data and b) we can extend it without worrying about 
compatibility:

struct Foo {
   int a;
   PrivateFoo *p;
};

We can still add public members if needed:

struct Foo {
    int a;
    void *private;
    int b;
};

'private' points to a private data structure that is not be visible to clients. 
There you can conditionally enable members without problems:

struct PrivateFoo {
#ifdef USE_BAR
    struct MyFeature feature;
#endif
};

MyFeature could be in a seperate source file together with your methods and it 
only gets compiled when needed.

Again, have a look at the "t_canvas_private" struct and the "gl_privatedata" 
member of "_glist" (aka "t_canvas") and do the same for "_editor", e.g.:

in g_canvas.h:

typedef struct _editor {
    ...
    void *e_privatedata;
} t_editor;

in g_editor.c:

#ifdef HAVE_KEYBOARDNAV
#include "g_keyboardnav.h"
#endif

typedef struct _editor_private {
#ifdef HAVE_KEYBOARDNAV
    t_keyboardnav keyboardnav;
#endif
} t_editor_private;

the "t_keyboardnav" struct is defined in "g_keyboardnav.h" and its methods 
implemented in "g_keyboardnav.c". Both only get compiled when needed.

Hope this makes sense.

Christof
_______________________________________________
Pd-dev mailing list
[email protected]
https://lists.puredata.info/listinfo/pd-dev

Reply via email to