[Saga-devel] Adding a new (overloaded) method to an adaptor
Hartmut Kaiser
hkaiser at cct.lsu.edu
Fri Jan 16 08:29:10 CST 2009
Paul,
> >It depends. If your new function should be exposed through the SAGA
> API then
> >you need to add it not only to the adaptor (obviously) but to the
> package as
> >well. In this case it's the easiest to make the function names unique.
> >Overloading function names is possible, but requires additional
> attention
> >while writing the adaptor registration functionality in the package.
>
> >If your new function is just something you need inside your adaptor
> you can
> >name it as you like, but you should avoid choosing a name similar to
> any
> >name used for the exposed functions (usually starting with sync_... or
> >async_...).
>
> >This limitation is due to the automagic behind adaptor function
> >registration. Choosing a name similar to the exposed CPI functions
> confuses
> >this detection magic. Which is what you're seeing.
>
> >HTH
> >Regards Hartmut
>
> Hartmut,
>
> The new function needs to be exposed through the SAGA API and ideally
> have the same name but be overloaded.
>
> I've added it to the adaptor and the package (the Service Discovery
> class and its corresponding implementation class). I've done as much
> of the macro-magic as I can but am not sure how to do the function
> registration.
>
> So, how would I go about registering this overloaded function as we
> don't really want to use a different function name.
The experience shows it to be the best to choose non-unique names for the
adaptor level, even if the names are overloaded at the API level. These
names are not visible to the user anyways, no harm done. But this involves
some trickery :-P
I'ld suggest you look at the job package, where we overloaded the
job_service::run_job function:
job run_job(std::string commandline, std::string hostname,
saga::job::ostream& stdin_stream, saga::job::istream&
stdout_stream,
saga::job::istream& stderr_stream)
and
job run_job(std::string commandline, std::string hostname = "")
These names in the API are mapped to different names on the adaptor level
(run_job and run_job_noio). This is done the following way:
API (façade):
- job_service.hpp as usual
- job_service.cpp:
SAGA_CALL_IMP_5 (service, run_job, std::string, std::string,
saga::job::ostream&, saga::job::istream&,
saga::job::istream&)
SAGA_CALL_IMP_2_EX (service, run_job, run_job_noio, std::string,
std::string)
The second one maps the name!
Impl:
- job_service.hpp/job_service.cpp as usual, but using the new name:
SAGA_CALL_IMPL_DECL_5(run_job, std::string, std::string,
saga::job::ostream&, saga::job::istream&, saga::job::istream&)
SAGA_CALL_IMPL_DECL_2(run_job_noio, std::string, std::string)
Now, on the adaptor level you have to use the different names as well:
void sync_run_job(saga::job::job & ret,
std::string commandline, std::string host,
saga::job::ostream& in, saga::job::istream& out,
saga::job::istream& err);
void sync_run_job_noio(saga::job::job & ret,
std::string commandline, std::string host);
Last, the function registration has to be done for both adaptor functions:
SAGA_REGISTER_MEMBER(retval, info, base_cpi, Derived, run_job, prefs);
SAGA_REGISTER_MEMBER(retval, info, base_cpi, Derived, run_job_noio,
prefs);
Well, the actual job package is more complex than that because of other
specifics (in addition, the functions are overloaded in the CPR package
which derives from the job), but the essence should be clear. The bottom
line is that everything (except one thing) is exactly as if you were using
different names altogether. The difference is in the cpp file of the API
(facade), where you have to use the ..._EX macro to map the name.
HTH
Regards Hartmut
More information about the saga-devel
mailing list