Collections-C icon indicating copy to clipboard operation
Collections-C copied to clipboard

linked list with signals

Open mame98 opened this issue 8 years ago • 6 comments

I would like to see a list which is basicly a linked list, but you should be able to add callback functions for the following actions:

  • new item added
  • item removed

Similar to: ObservableCollections in C#

I would want to implement this. What do you think? would you like to see it implemented in the default linked list or in a seperate structure?

mame98 avatar Mar 16 '16 16:03 mame98

Hi @mame98 ,

Thats a good point. I think it's the best to implement a wrapper around the base linked list. This will help us keep the linked list clean with only the functions it's supposed to provide.

  • Ankur

ankurdh avatar Mar 16 '16 17:03 ankurdh

Yeah, I will work on this soon...

mame98 avatar Mar 16 '16 20:03 mame98

This is not bad idea. The most convinient way to implement this would be to keep the callback pointers in the container structure and just call them from appropriate functions if they are set. Two extra pointers shouldn't make much of a difference unless you're using lots of small containers, where the container structures themselves use a significant portion memory.

So basically if you wanted to set a callback you would do something like this:

ArrayConf ac;
array_conf_init(&ac);

ac.on_add     = my_add_callback;
ac.on_remove  = my_remove_callback;

Array *array;
array_new_conf(&ac, &array); // make a new array with this configuration

This is pretty easy to implement. We just need to add some extra function pointers to container and conf structures and then make sure to call them from appropriate function if they are set.

enum cc_stat array_add(Array *a, void *e) {
    ....
    if (a->on_add) 
        a->on_add() // call if set
}

... and so on

srdja avatar Mar 18 '16 14:03 srdja

Okay, I think the way @ankurdh suggested is a bit better, because as you said that if you do not want the callbacks you are wasting memory. You would just need to have some small wrapper functions which call the list functions but also trigger the callbacks...

So I would create a small structure like:

typedef struct
{
    List *list;
    on_add;
    on_delete;
    and so on...
}WatchList;

Then you would just implement an (inline) function to get the List from this WatchList. Also if there would be a small function to convert a 'normal' list to a WatchList it would be pretty easy to use...

What do you think?

mame98 avatar Mar 18 '16 14:03 mame98

I don't think that the solution @ankurdh proposed is practical. For one you wouldn't be able to use a List and WatchList interchangeably. Any peace of code that expects a List wouldn't be able to use the WatchList because its essentially a different container with a different API. Another thing is that the wrapper seems redundant because if the caller already knows that it's calling a function that will trigger a callback then you might as well just pass a regular List and a callback to that caller. The point is that this approach just needlessly complicates matters without much benefit.

This type of thing makes sense in languages that have some kind of inheritance where you can pass around a super type and where you can have modified behaviour in sub types, but trying to do this in C is really ugly.

srdja avatar Mar 18 '16 15:03 srdja

Yeah seems right... I will work on your solution tomorrow...

mame98 avatar Mar 18 '16 19:03 mame98