www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - 2 Questions: Do I need an interface & C++ -> D code part, how?

reply Benjamin Schulte <Aldoric gmx.de> writes:
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
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
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 19 2007
parent Benjamin Schulte <Aldoric gmx.de> writes:
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;
}
May 20 2007