Proposal for an extended callbacks field
Augie Fackler
lists at durin42.com
Tue Jul 24 21:15:17 EDT 2007
Folks,
My summer of code student (Andreas Monitzer) has hit a snag in
extending the protocol plugin for XMPP because of the design of the
callbacks. I know that a full reworking of the callback system can't
happen until libpurple 3.0, so we'd like to propose a solution that
would patch over this problem in the interim. The proposal is below.
We'll implement the change, naturally, but I thought it prudent to
discuss the design some and get feedback before using one of the
reserved padding pointers and going to the effort to implement the fix.
Thanks,
Augie Fackler
_The Problem_
Libpurple uses a static struct to describe the callbacks that define
a prpl (this is only an excerpt):
struct _PurplePluginProtocolInfo
{
void (*set_info)(PurpleConnection *, const char *info);
unsigned int (*send_typing)(PurpleConnection *, const char *name,
PurpleTypingState state);
void (*get_info)(PurpleConnection *, const char *who);
void (*set_status)(PurpleAccount *account, PurpleStatus *status);
void (*set_idle)(PurpleConnection *, int idletime);
void (*change_passwd)(PurpleConnection *, const char *old_pass,
const char *new_pass);
void (*add_buddy)(PurpleConnection *, PurpleBuddy *buddy,
PurpleGroup *group);
void (*add_buddies)(PurpleConnection *, GList *buddies, GList
*groups);
/* room list serialize */
char *(*roomlist_room_serialize)(PurpleRoomlistRoom *room);
void (*_purple_reserved1)(void);
void (*_purple_reserved2)(void);
void (*_purple_reserved3)(void);
void (*_purple_reserved4)(void);
};
This works fine as long as you don't want to change anything. One
important thing to be careful about is to not change the struct's
size, if you don't want to force the plugin devs to recompile their
work. This means that adding new callbacks is limited to four
functions right now. Since this is very little, Sean tries to avoid
adding things at any cost, effectively nullifying the ability to add
new callbacks. This has already added a workaround for setting the
registration callback for XMPP, where an additional function outside
this struct is used. This creates a problematic inconsistency that
complicates the use of the libpurple API for newcomers.
_The Solution_
The proposed solution would use a hashtable, mapping char * -> void
(*)(...):
struct _PurplePluginProtocolInfo
{
...
GHashTable *additional_functions;
void (*_purple_reserved1)(void);
void (*_purple_reserved2)(void);
void (*_purple_reserved3)(void);
};
Callbacks other than the ones listed in the struct directly would
then be added to the hashtable, therefore preventing any further need
to spend precious padding pointers on callback functions. This allows
further growth of the library without having to run the risk of
binary incompatibilities or requiring inconsistent hacks.
_Conclusion_
This solution will solve the issue at hand until a larger update can
be done (like libpurple 3.0). Sean told us that libpurple is planned
to move to GObject then, so things will have to be reevaluated at
that point. However, setting the callbacks in stone stands in the way
of enhancements to the libpurple library, and thus should be avoided.
However, it is possible to fix that in the current code, without
sacrificing binary compatibility.
More information about the Devel
mailing list