Re: [dev] proposal: ServiceDecl

2005-11-09 Thread Daniel Boelzle
 One nit: since the automatic implementation name derivation looks kind
 of fragile (and most of the time, I _do_ declare my service
 implementations in anonymous namespaces) - how about disabling that
 feature by default? I have the impression that not much of OOo
 development outside Sun takes place on Windows, and specifying one
 (more) string at the constructor is really not that much overhead...

Yes, the current implementation disallows the use of anonymous
namespaces (at least on Windows, the dll cannot be registered).
I agree, it is really not much work to specify an implementation name,
but it would be nice to get rid of it.  IMO the current (though not
specified) rule inserting a comp. into the service name to make an
implementation name, e.g.

org.openoffice.package.MyService =
org.openoffice.comp.package.MyService

is even more fragile.

I think using a named namespace (instead of an anonymous) is not really
overhead, and, with the prepended library name, the implementation name
is unique:
- double class definitions in the same library leads to link error
- use of anonymous namespace for class_ leads to registration error

Of course, the safe solution would be a globally unique identifier
(GUID), but much more overhead.

regards,
-Daniel

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [dev] proposal: ServiceDecl

2005-11-09 Thread Frank Schönheit - Sun Microsystems Germa ny
Hi Daniel,

 I'd like to present/discuss a recent helper I have developed which IMO
 simplifies the implementation of UNO services in C++ a lot.
 Using the following (what I call) service declaration, the developer can
 concentrate on implementing her service's interfaces, e.g.

again, you managed to make one of my recently-introduced helper classes
(in a CWS not yet integrated) obsolete, with a much cooler solution. I
hope you're not going to make a hobby out of this :)

 class MyImpl : cppu::WeakImplHelper2XInterface1, XInterface2 {...};
 
 There is no need to implement lang::XServiceInfo nor

Does this mean that at runtime, if an object of this class is
instantiated, it in fact does not support XServiceInfo? Or do your
factories create a wrapper around the real class, which adds this interface?
Basically, can a Basic script developer still do something like:
  barServer = createUnoService( com.sun.star.foo.BarServer )
  MsgBox barServer.ImplementationName
?

 You can have a look at the implementation on cws dbo510 (tag
 cws_src680_dbo510):
 comphelper/inc/comphelper/servicedecl.hxx
 comphelper/inc/comphelper/makesequence.hxx
 comphelper/source/misc/servicedecl.cxx

Those are good candicates for cppuhelper, IMO.

Thanks  Ciao
Frank

-- 
- Frank Schönheit, Software Engineer [EMAIL PROTECTED] -
- Sun Microsystems  http://www.sun.com/staroffice -
- OpenOffice.org Database   http://dba.openoffice.org -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [dev] proposal: ServiceDecl

2005-11-09 Thread Daniel Boelzle

Hello Niklas,

namespace sdecl = comphelper::service_decl;
sdecl::ServiceDecl const myDecl(
sdecl::class_MyImpl(),
org.openoffice.MyService,
[optional my.implementation.name] );
 
 
 If used as a global object, with a constructor that is executed when the 
 DLL is loaded, that won't help with start-up performance.

IMO it doesn't matter whether you create that data (mostly the
implementation name) at the point of loading the library or slightly
later when the UNO service needs to be instantiated.
But I agree that those ctors are executed even though not all services
may be needed from that library, e.g. at the extreme if only one of 100
is used.  Thus, it makes sense to optimize the current ctors, so they
only save the passed char pointers, late-initializing OUString/Sequence
objects when needed.  For the case of multiple supported services we
could e.g. use a separated list of service names like
Service1;Service2;  All in all, I assume runtime performance is
hardly affected then.

regards,
-Daniel

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [dev] proposal: ServiceDecl

2005-11-09 Thread Frank Schönheit - Sun Microsystems Germa ny
Hi Daniel,

 IMO it doesn't matter whether you create that data (mostly the
 implementation name) at the point of loading the library or slightly
 later when the UNO service needs to be instantiated.

It might be everything from slightly later to never (because perhaps
sevice Foo from lib A is needed, but Bar isn't at all).

I used to use the following pattern to prevent this:

- implement
  extern C void SAL_CALL createServiceInfo_Foo()
  {
static sdecl::ServiceDecl const myDecl(
  sdecl::class_MyImpl(),
  org.openoffice.Foo, org.openoffice.comp.Foo );
  }
  beside my service implementation
- call createServiceInfo_Foo from within component_* functions, for
  every implementation in the library

This is slightly more uncomfortable than a global variable, but should
prevent all its drawbacks.

Ciao
Frank

-- 
- Frank Schönheit, Software Engineer [EMAIL PROTECTED] -
- Sun Microsystems  http://www.sun.com/staroffice -
- OpenOffice.org Database   http://dba.openoffice.org -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [dev] proposal: ServiceDecl

2005-11-09 Thread Jürgen Schmidt

Thorsten Behrens wrote:

Daniel Boelzle [EMAIL PROTECTED] writes:



I'd like to present/discuss a recent helper I have developed which IMO
simplifies the implementation of UNO services in C++ a lot.

[...]

So what do you think?  Comments, please.



Great stuff! Always having to write so much boilerplate has gotten to
my nerves.


Of course it's a cool feature but i want to mention that the new 
skeletonmaker tool can help a lot to reduce the coding effort for UNO 
objects and components. The tool is not officially announced because 
there is still some work to do but you can start using it and give feedback.


dump mode:
- the tools can dump method declaration of interfaces and all supported 
interfaces of services to stdout so that you can easily copy this stuff 
in your source file.


- it can generate complete method bodies to stdout (default return, 
forwarding, composition, inline or with classname, ...)


component mode:
- it can generate complete component skeletons (buidlable, deployable) 
and you have to concentrate on the real implementation only



Supported languages Java and C++

More information will follow soon

Juergen





One nit: since the automatic implementation name derivation looks kind
of fragile (and most of the time, I _do_ declare my service
implementations in anonymous namespaces) - how about disabling that
feature by default? I have the impression that not much of OOo
development outside Sun takes place on Windows, and specifying one
(more) string at the constructor is really not that much overhead...

Cheers,



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



[dev] proposal: ServiceDecl

2005-11-08 Thread Daniel Boelzle

Hello,

I'd like to present/discuss a recent helper I have developed which IMO
simplifies the implementation of UNO services in C++ a lot.
Using the following (what I call) service declaration, the developer can
concentrate on implementing her service's interfaces, e.g.

class MyImpl : cppu::WeakImplHelper2XInterface1, XInterface2 {...};

There is no need to implement lang::XServiceInfo nor
lang::XInitialization (if the service expects arguments for creation).

Next, one just has to declare the above class defining a service
declaration object:

namespace sdecl = comphelper::service_decl;
sdecl::ServiceDecl const myDecl(
sdecl::class_MyImpl(),
org.openoffice.MyService,
[optional my.implementation.name] );

The ServiceDecl ctor expects as

1st parameter: a comphelper::service_decl::class_ object as first
parameter (which I further explain shortly)

2nd parameter: a single name or a uno::Sequencertl::OUString stating
the supported service names

3rd parameter (optional): an implementation name; if this has been
omitted, the implementation name will be generated out of MyImpl'S
type_info (which I will explain shortly).

The class_ object states the user's implementation class, which by
default is required to define a constructor taking a

uno::Referenceuno::XComponentContext

as its sole argument.  If the user requires service arguments for
construction, she can customize the class_ object, using

sdecl::class_MyImpl, sdecl::with_argstrue ()

In this case, the user's implementation class is required to define a
constuctor taking

uno::Sequenceuno::Any,
uno::ReferenceXComponentContext

If the user needs to execute special post processing code, e.g. for
registering the newly created object as a listener, then she can specify
a function/functor, too:

sdecl::class_MyImpl, ...(postProcessing)

That functor needs to be of the following form, e.g.

uno::Referenceuno::XInterface postProcessing( MyClass * p );

and gets the _yet unacquired_ pointer.

If the implementation name ought to be generated, then the mangled C++
name including the user's class is taken into account as well as the
library name, e.g. a generated name may look like:

deployment680mi.uno.dll;[EMAIL PROTECTED]@dp_manager@@
(MSVC, using type_info::raw_name())

deployment680li.uno.so;N10dp_manager7factory25PackageManagerFactoryImplE
(gcc 3.4.1, using type_info::name())

There is a flaw when the user uses an anonymous namespace for the
implementation class:
- At least on Windows there is the possibility that the generated
implementation name is not unique (e.g. same anonymous class name in two
different compilation units within same dll).
- g++ mangles the whole compilation path into the anonymous symbol (+
time stamp etc.).  This will avoid the possibility to just quickly
compile and link a library with debug and exchange without
re-registering it, which I fear leads to subtle confusion.
IMO, sad but true, using a anonymous namespace is a bad idea here, so I
currently disallow this leading to a runtime error when the library is
loaded, stating these problems (currently on Windows only; easy to
detect).  Implementation classes have to be declared in a _named_
namespace (if any).

When it comes to exporting the necessary component_xxx() functions,
there are new helper functions that can deal with a variable number of
ServiceDecl objects:

extern C {
void SAL_CALL component_getImplementationEnvironment(
const sal_Char ** ppEnvTypeName, uno_Environment ** )
{
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

sal_Bool SAL_CALL component_writeInfo(
lang::XMultiServiceFactory * pServiceManager,
registry::XRegistryKey * pRegistryKey )
{
return component_writeInfoHelper(
pServiceManager, pRegistryKey, myDecl, myDecl2, ... );
}

void * SAL_CALL component_getFactory(
sal_Char const * pImplName,
lang::XMultiServiceFactory * pServiceManager,
registry::XRegistryKey * pRegistryKey )
{
return component_getFactoryHelper(
pImplName, pServiceManager, pRegistryKey, myDecl, myDecl2, ...);
}
} // extern C

By default, the component_xxxHelper() functions can cope with up to 8
declarations (can be increased using
COMPHELPER_SERVICEHELPER_COMPONENT_HELPER_MAX_ARGS before including
comphelper/servicedecl.hxx).

You can have a look at the implementation on cws dbo510 (tag
cws_src680_dbo510):
comphelper/inc/comphelper/servicedecl.hxx
comphelper/inc/comphelper/makesequence.hxx
comphelper/source/misc/servicedecl.cxx

For testing purposes, I have adopted the deployment API implementation
(module desktop) which comes with quite a lot services.

So what do you think?  Comments, please.

regards,
-Daniel

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]