Thread overview
2 Questions: Do I need an interface & C++ -> D code part, how?
May 19, 2007
Benjamin Schulte
May 19, 2007
Daniel Keep
May 20, 2007
Benjamin Schulte
May 19, 2007
Hi,

I've got two questions about D - all containing those class structure:

class Event
{
  this( ) { ... } /// Add event to eventlist
  ~this( ) { ... } /// Remove event from eventlist

  abstract Event[] getEventList( );
}

class MainLoopEvent : Event
{
  abstract void onMainLoop( );

  Event[] getEventList( ) { return events; }
  MainLoopEvent[] events;
}

-----

now my first question:
I've got another class, called MyApplication - I want to have class Application as base class and MainLoopEvent as 2nd base class. So I wrote:

class MyApplication : Application, MainLoopEvent { }

But I got an error, that MainLoopEvent has to be an interface. Is there now another way than saying:

interface EventInterface
{
  // EMPTY!!!
}

class Event : EventInterface
...

Would be nice if I don't have to create an empty interface, just to make D  happy.


---------------
2nd question:

MainLoopEvent has the method onMainLoop( );
Say we create a second class with Event as Base class

class AnotherEvent : Event
{
  abstract void onBeingHappy( int a, int b );
}

Now, now I need a new function. In C++ I could write a macro: (I mixed C++ with D to show you what I mean:)

#define callEvent(classType,event) foreach(Event e; event.getEventList() ) ((classType*)e)

I could now just call
callEvent(MainLoopEvent, myApplication)->onMainLoop( );
callEvent(AnotherEvent, myEvent)->onBeingHappy( 12, 31 );

At the moment my solution for MainLoopEvent looks like this:
	static void callMainLoop( )
	{
		// Call main loop event
		foreach( MainLoopEvent e; events ) e.onMainLoop( );
	}

But that's not my favorite way to do this, because I would have to rewrite this for every abstract method.

Might have some bugs in here, but I hope you understand what I mean. A template that calls methods I don't really know from the structure.




Thanks for every help : )
May 19, 2007

Benjamin Schulte wrote:
> Hi,
> 
> I've got two questions about D - all containing those class structure:
> 
> ...
> 
> now my first question:
> I've got another class, called MyApplication - I want to have class Application as base class and MainLoopEvent as 2nd base class. So I wrote:
> 
> class MyApplication : Application, MainLoopEvent { }
> 
> But I got an error, that MainLoopEvent has to be an interface. Is there now another way than saying:

D only has single inheritance; you cannot inherit from multiple base classes.  Instead, the normal practice is to inherit from one base class and many interfaces.

> ---------------
> 2nd question:
> 
> MainLoopEvent has the method onMainLoop( );
> Say we create a second class with Event as Base class
> 
> class AnotherEvent : Event
> {
>   abstract void onBeingHappy( int a, int b );
> }
> 
> Now, now I need a new function. In C++ I could write a macro: (I mixed C++ with D to show you what I mean:)
> 
> #define callEvent(classType,event) foreach(Event e; event.getEventList() ) ((classType*)e)

I imagine the macro would not have been quite so easy to read had it been written for C++ :P

> I could now just call
> callEvent(MainLoopEvent, myApplication)->onMainLoop( );
> callEvent(AnotherEvent, myEvent)->onBeingHappy( 12, 31 );
> 
> At the moment my solution for MainLoopEvent looks like this:
> 	static void callMainLoop( )
> 	{
> 		// Call main loop event
> 		foreach( MainLoopEvent e; events ) e.onMainLoop( );
> 	}
> 
> But that's not my favorite way to do this, because I would have to rewrite this for every abstract method.
> 
> Might have some bugs in here, but I hope you understand what I mean. A template that calls methods I don't really know from the structure.

You could try something like this:

void callEvent(EventType, DgType)(DgType dg)
{
    foreach( e ; events )
        if( auto mle = cast(EventType)e )
            dg(mle);
}

callEvent!(MainLoopEvent)((MainLoopEvent e){e.onMainLoop();});

It's hard to suggest what to do since I'm not 100% sure what you're trying to accomplish.  Looking at D from a C++ perspective is tricky since D is *not* C++, nor is it descended from it.

If you're doing GUI code, you might want to look at DFL (http://www.dprogramming.com/dfl.php) which might give you some ideas on how to do event callbacks.

For instance, I wouldn't bother with classes myself, I'd just use delegates, or the Signal and Slot stuff in std.signals.  Like I said, have a poke around, and keep in mind that D is not a superset of C++, so there will be things you can't directly translate (like multiple inheritance).  Anything in C you can generally assume behaves in roughly the same way, but outside of that, be careful.

	-- Daniel

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

http://xkcd.com/

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
May 20, 2007
Okay, that's really a bad point for D in my oppinion.

It's really hard to convert the easiest things to D now without using a class for this case.

Like I had before:

Event[] events;

class Event
{
  void addEvent( )
  {
    // Add to events and save index in array in 'thisIndex'
  }

  void remEvent( )
  {
    // Remove event from array by replacing 'thisIndex' with Event
    // at the last position of the array
  }

  int thisIndex;
}