[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-multimedia
Subject:    Re: Flat SmartWrappers
From:       Stefan Westerfeld <stefan () space ! twc ! de>
Date:       2000-04-09 20:07:13
[Download RAW message or body]

   Hi!

First of all: I have now committed the smartwrapper everywhere changes I did
over the weekend. That means (from CVS log):

---------------------------------------------------------------------------
SmartWrappers everywhere. Developers should no longer need to care about
reference counting. _copy(), _release(), _var, _base* and similar disappear
from most code (only some internals and generated code will still use them).
 
- the language binding for parameters and returncodes has been changed to
  use SmartWrappers
- neither _var wrappers are generated by mcopidl automatically, nor are they
  used throughout the code
- an Object smartwrapper now exist, the base class is now Object_base like
  for any other interface                                                       
---------------------------------------------------------------------------

I have added lots of things into the TODO as well. This change will need
some time to settle down (maybe a few days or so), after that, we should
do the binary size comparision with a version before all smartwrappers,
but I don't expect that the whole thing has to be reverted due to size
problems.

On Sat, Apr 08, 2000 at 05:13:00PM +0100, Nicolas Brodu wrote:
> That works fine here as well. I just put back the use of the ?: operator because
> it increases the speed by half (150%) on my system, effectively rendering the
> SmartWrappers more efficient than the _var code in the first 2 speed test.
Okay.

> > Casting is done via operators. So if D inherits from A, it has an
> > 
> >   inline operator A()
> > 
> > to do the casts. So it works the same as before, just without inheritance.
> > One problem is still that when writing A(d), where "d" is a D class, its
> > not clear whether a conversion to D_base* and then to A (from A_base*) or
> > to A and then to A via copy constructor is requested. This should go away
> 
> I think so, since D isn't a child of A anymore.
> 
> > once _base stuff disappears a bit more and the operator is no longer needed.
> 
> ?? There will still be a need for a A(const D&) constructor, or equivalent.
> Perhaps the solution would be a A(const SmartWrapper&) constructor, so that it
> could accept any type, including D. Then, the _cast() will check if the
> assignment is legal or not. I think it's OK, do you?

I don't think we should have something like this implicit. You can do far too
much things wrong. Think of

  SimpleSoundServer obj = ...;
  [ some lines of code ]
  PlayObject p(obj);

I'd like to have such big errors noticed at compile time when possible. Still,
you cant do an A(const D&) constructor, since A will never know that D
inherits it (that may happen later...). But having an operator A() in D does
the trick (see testwrapper.cc).

I made conversion to D_base * now explicit (since you do far too many errors
with implicit conversion anyway, and nobody should need it), and now the
compiler knows what you want if you write

D d;
A a(d);

before, there were two choices
- convert to D_base*, downcast to A_base* and make an A from the A_base*
  (which would make the reference count end up wrong)
- use D.operator A(), to make an A, and then A(const A&)

now only the second remains.

> > Also the start() function still causes problems - something has to be renamed
> > there.
> 
> Sure. The SynthModule class is a bit special, since it doesn't have an
> implementation but instead a StdSynthModule class that inherits from the _base,
> and not the _skel.
> The child synth_XXX then inherits from StdSynthModule, and its start() method
> isn't the same than the _node()->start().
> 
> What I mean is since that is not quite standard, we could:
> - Put the SynthModule code in a .h/.cc file, and remove it from the idl.
> - Detect in mcopidl if a given module uses streams. If yes, silently add a
> parent corresponding to the present SynthModule.
> 
> Since we already generate code conditionally to having streams, and include
> flowsystem.h the same way, this seems the logical continuation. Moreover, we
> would then have a 'real' stream keyword in the idl, independant of what parent
> the interface has declared. It will also be easier to add new stream type in the
> future (like video...). What do you think?

There are three interfaces that you need to get right:

1) MCOP generated code <=> FlowSystem
2) Object implementation <=> FlowSystem
3) C++-Developer <=> FlowSystem

1)

If an object has streams, the flowsystem needs to know this. Currently,
objects do so by using initStream and similar. Stream carrying objects
also register themselves with the FlowSystem upon startup

2)

* things that the FlowSystem wants object implementations to do

The object implementation has methods that get called when it gets started
and stopped (these are called by the flowsystem). AutoSuspend is also
something that falls into that category.

A streams carrying object developer needs to/may implement these. They
are called initialize()/start() for initialization and unInitialize() for
deinitialization.

This is done by the SynthModule interface.

* things that the object impl wants the flowsystem to do

_needMore falls into that category; this is also done by _node()

3)

C++ Developers are currently supplied over the SchedulingNode _node(), which
is now wrapped in various ways through SmartWrappers.


The current code works in such a way that you can exchange the FlowSystem
implementation. When you do, you also can mostly exchange the interfaces
that are used in 2. 1 and 3 stay consistend.

Our current problems arise from the fact that the names use in SynthModule
clash with those used in the interface in 3.

Maybe one reasonable approach for resturcturing that all would be the
following. Move the following to the official Object interface

string toString();

// C++ developer interface (as in 3)
void start();
void stop();

// Stream implementation interface (as in 1)
void streamInit();
void streamStart();
void streamStop();
AutoSuspend streamSuspendable();

What I don't like with the naming is that streamInit() and streamStart()
doesn't make really clear that streamStop() should undo the effects of
streamInit().... basically this is in two phases to allow the following:

1) streamInit() all modules that should be started
2) streamStart() all modules

If streamInit() involves things like creating widgets, talking to other
MCOP objects and whatever else (time intensive), you can with that way
of starting still ensure that all modules start at the same time.

Anyway, moving these to Object would effectively get rid of SynthModule...
what do you think? Maybe you can read a bit in the code, and in the TODO...

I'll do that too... this restructuring should be done thoughtful for not
breaking anything important ;)

   Cu... Stefan
-- 
  -* Stefan Westerfeld, stefan@space.twc.de (PGP!), Hamburg/Germany
     KDE Developer, project infos at http://space.twc.de/~stefan/kde *-

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic