|
From: Luiz A. D. de L. <lui...@gm...> - 2011-05-23 14:27:21
|
---
Luiz Angelo Daros de Luca, Me.
lui...@gm...
2011/5/23 Chris Frey <cd...@fo...>
> On Sun, May 22, 2011 at 05:57:17PM -0300, Luiz Angelo Daros de Luca wrote:
> > Indeed, I need it outside the callback functions :-)
> > As I'm using a script language that cannot be called as a callback
> function,
> > I implemented a "callback router" function. Let me explain:
> >
> > plugin or sink (in ruby) calls my_set_xxx_fn
> > my_set_xxx_fn saves this ruby callback in a struct living in
> user_data/data
> > my_set_xxx_fn call osync...set_xxx_fn to use my callback_router function
> >
> > When osync calls the callback:
> >
> > callback_router reads the struct in user_data/data
> > callback_router calls ruby callback funcion
> >
> > So, when "my_set_xxx_fn saves the ruby callback in user_data/data", it
> needs
> > to read the current data. I cannot simply realloc a new
> > data struct because it is also used for other callbacks and non-callback
> > stuff. Also, if there was a previous callback defined, I need to "unref"
> it
> > from ruby world and let the Garbage collector do its job.
>
> I think I understand. The only alternative for you, would be to track
> the sinks and the userdata in your own hashtable?
>
This is exactly what I am doing :-). However, I use a simple osynclist as I
will not get too much sinks.
> When the ruby plugin calls my_set_xxx_fn, does it pass in an
> OSyncObjTypeSink
> pointer? Because that's the only way opensync can find the user data.
> Where would you get the sink pointer from?
>
Yes, I have all pointers from C that I need (thanks for SWIG). When I call
some ruby method, I use SWIG functions in order to convert all C pointers
into something that ruby can give back to other swig methods. _xxx are swig
object (aka C pointers). This is a small example to list sinks. All
callbacks are set in superclass Opensync::Plugin. I just need to reimplement
them.
module Opensync
class Plugin < OSyncObject
def initialize(_self, _env)
(...)
self.initialize=Proc.new{|_plugin,_info,_error|
initialize_called(_plugin,_info,_error)}
(...)
end
def initialize_called(_plugin,_info,_error)
Opensync.error=_error
info=Info.for(_info)
initialize0(info)
end
class Info < OSyncObject
map_methods /^osync_plugin_info_/
represent SWIG::TYPE_p_OSyncPluginInfo
end
end
end
class RubyFileSync < Opensync::Plugin
def initialize(_self, _env)
super(_self, _env)
self.name="ruby-file-sync"
self.longname="File Synchronization Plugin"
self.description="Plugin to synchronize files on the local filesystem"
end
def initialize0(info)
config = info.config
p info.objtype_sinks
end
end
FYI, initialize is a special ruby method called from Class.new.
map_methods maps all functions from SWIG that matches the regexp, converting
SWIG types to my ruby osync types when needed and available So, I'm using
some dynamic code generation. *_get/set_* into getters and setters, new and
unref into class methods alloc and unref and all others as normal instance
methods. That's why objtype_sinks is not defined in class Info. Less code,
less bugs. However, removing the ifs and cases, it would just looks like
this:
Class Info
def objtype_sinks
Opensync::osync_objtype_sink_get_objtype_sinks(@_self).collect
{|_sink| Sink.for(_sink) }
end
end
It is a little different approach from what I saw in python-module plugin.
All logic is inside ruby world and C code is just for wrapping.
>
> > BTW, why plugin and sink has different names for its data function?
> set_data
> > and sink set_userdata. Are they planned for different uses? Maybe I'm
> > missing something or I am just abusing it ;-)
>
> All the sync callbacks get passed the sink userdata. That is, the
> functions
> that you register like this:
>
> osync_objtype_sink_set_connect_func(sink, connect);
> osync_objtype_sink_set_disconnect_func(sink, disconnect);
> osync_objtype_sink_set_get_changes_func(sink, contact_get_changes);
> osync_objtype_sink_set_commit_func(sink, commit_change);
> osync_objtype_sink_set_sync_done_func(sink, contact_sync_done);
>
> But the plugin level callbacks, take the plugin user data:
>
> osync_plugin_set_initialize(plugin, initialize);
> osync_plugin_set_finalize(plugin, finalize);
> osync_plugin_set_discover(plugin, discover);
>
>
Sorry, I guess I wasn't clear. I just asked why the name of
osync_objtype_sink_set_userdata is this and not osync_objtype_sink_set_data
like in osync_plugin_set_data. I was worried that
osync_objtype_sink_set_userdata might
be designed to store something other than a pointer for plugin developer own
use. If it is just like what osync_plugin_set_data is for plugins but for
sinks, I'm fine.
Regards,
> - Chris
>
>
>
> ------------------------------------------------------------------------------
> What Every C/C++ and Fortran developer Should Know!
> Read this article and learn how Intel has extended the reach of its
> next-generation tools to help Windows* and Linux* C/C++ and Fortran
> developers boost performance applications - including clusters.
> http://p.sf.net/sfu/intel-dev2devmay
> _______________________________________________
> Opensync-devel mailing list
> Ope...@li...
> https://lists.sourceforge.net/lists/listinfo/opensync-devel
>
|