// double_dispatch_static.C
// ----------------------------------------------------------------
// COMP 290-001: Algorithm Library Design, Lutz Kettner, 01/11/2000
// Example for (non-extendible) double dispatch.

#include <iostream.h>

// forward declaration
struct Ship;
struct Station;
struct Asteroid;

struct Game_object {
    virtual void collision( Game_object* other) = 0;
    virtual void collision2( Ship*     other) = 0;
    virtual void collision2( Station*  other) = 0;
    virtual void collision2( Asteroid* other) = 0;
    virtual ~Game_object() {}
};
struct Ship : public Game_object {
    virtual void collision( Game_object* other) {
        // this (of type Ship) collides here with other, call second dispatch
	other->collision2( this);
    }
    virtual void collision2( Ship*     other) {
        cout << "Ship collides with Ship." << endl;
    };
    virtual void collision2( Station*  other) {
        cout << "Ship collides with Station." << endl;
    };
    virtual void collision2( Asteroid* other) {
        cout << "Ship collides with Asteroid." << endl;
    };
};
struct Station : public Game_object {
    virtual void collision( Game_object* other) {
	other->collision2( this);
    }
    virtual void collision2( Ship*     other) {
        cout << "Station collides with Ship." << endl;
    };
    virtual void collision2( Station*  other) {
        cout << "Station collides with Station." << endl;
    };
    virtual void collision2( Asteroid* other) {
        cout << "Station collides with Asteroid." << endl;
    };
};
struct Asteroid : public Game_object {
    virtual void collision( Game_object* other) {
	other->collision2( this);
    }
    virtual void collision2( Ship*     other) {
        cout << "Asteroid collides with Ship." << endl;
    };
    virtual void collision2( Station*  other) {
        cout << "Asteroid collides with Station." << endl;
    };
    virtual void collision2( Asteroid* other) {
        cout << "Asteroid collides with Asteroid." << endl;
    };
};


int main() {
    Game_object* ship     = new Ship;
    Game_object* asteroid = new Asteroid;
    Game_object* station  = new Station;

    ship->collision( ship);
    ship->collision( station);
    ship->collision( asteroid);
    station->collision( ship);
    station->collision( station);
    station->collision( asteroid);
    asteroid->collision( ship);
    asteroid->collision( station);
    asteroid->collision( asteroid);
}

// EOF //

