//===========================================================================//
// File:	receiver.tst                                                        //
// Project: MUNGA           Brick: Dynamic Dispatch                          //
// Contents: Verify routines for MessageHandlerSet, Derivation and Receiver    //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 10/19/94  JMA  Initial coding.                                            //
// 11/02/94  JMA  Made compatible with SGI CC                                //
// 11/03/94  ECH  Made compatible with BC4.0                                 //
// 11/05/94  JMA  Made compatible with GNU C++                               //
// 12/01/94  JMA  Made compatible with SGI CC                                //
// 12/04/94  JMA  Moved Message under Receiver, merged in message.tst        //
//---------------------------------------------------------------------------//
// Copyright (C) 1994, Virtual World Entertainment, Inc. All Rights reserved //
//                      PROPRIETARY AND CONFIDENTIAL                         //
//===========================================================================//

#include "AdeptHeaders.hpp"

#include "Receiver_Test.hpp"

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Alpha ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Alpha::ClassData*
	Alpha::DefaultData = NULL;

const Receiver::MessageEntry
	Set_1[]=
{
	MESSAGE_ENTRY(Alpha, Method0),
	MESSAGE_ENTRY(Alpha, Method1)
};

RegisteredClass::ClassID
	Alpha::alphaClassID;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	Alpha::InitializeClass()
{
	alphaClassID = RegisteredClass::AllocateTemporaryClassID();
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			alphaClassID,
			"Alpha",
			Receiver::DefaultData,
			ELEMENTS(Set_1),
			Set_1
		);
	Register_Object(DefaultData);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	Alpha::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

Alpha::Alpha(ClassData *class_data):
	Receiver(class_data)
{
	x = -1;
}

Alpha::~Alpha()
{
}

void
	Alpha::Method0MessageHandler(const Message*)
{
	x = 0;
}

void
	Alpha::Method1MessageHandler(const Message*)
{
	x = 1;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Beta ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Beta::ClassData*
	Beta::DefaultData = NULL;

const Receiver::MessageEntry
	Set_2[]=
{
	MESSAGE_ENTRY(Beta, Method1),
	MESSAGE_ENTRY(Beta, Method2),
	MESSAGE_ENTRY(Beta, Method3)
};

RegisteredClass::ClassID
	Beta::betaClassID;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	Beta::InitializeClass()
{
	betaClassID = RegisteredClass::AllocateTemporaryClassID();
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			betaClassID,
			"Beta",
			Alpha::DefaultData,
			ELEMENTS(Set_2),
			Set_2
		);
	Register_Object(DefaultData);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	Beta::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

Beta::Beta(ClassData *class_data):
	Alpha(class_data)
{
	x = -2;
}

Beta::~Beta()
{
}

void
	Beta::Method1MessageHandler(const Message*)
{
	x = 6;
}

void
	Beta::Method2MessageHandler(const Message*)
{
	x = 2;
}

void
	Beta::Method3MessageHandler(const Message*)
{
	x = 3;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Gamma ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Gamma::ClassData*
	Gamma::DefaultData = NULL;

const Receiver::MessageEntry
	Set_3[]=
{
	MESSAGE_ENTRY(Gamma, Method4)
};

RegisteredClass::ClassID
	Gamma::gammaClassID;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	Gamma::InitializeClass()
{
	gammaClassID = RegisteredClass::AllocateTemporaryClassID();
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			gammaClassID,
			"Gamma",
			Beta::DefaultData,
			ELEMENTS(Set_3),
			Set_3
		);
	Register_Object(DefaultData);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	Gamma::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

Gamma::Gamma():
	Beta(DefaultData)
{
	x = -3;
}

Gamma::~Gamma()
{
}

void
	Gamma::Method4MessageHandler(const Message*)
{
	x = 4;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Receiver ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//
//#############################################################################
//#############################################################################
//
bool
	Receiver::TestClass()
{
#if 0
	DEBUG_STREAM << "Starting Receiver test...\n";

	Alpha a;
	Beta b;
	Gamma c;
	Message
		m(0, sizeof(Message), 0, Message::DefaultFlags);

	//
	// Check construction stability
	//
	ChainIteratorOf<Derivation*>
		i(&Alpha::ClassDerivation->classDerivations);
	Verify(i.ReadAndNext() == Beta::ClassDerivation);
	Verify(i.GetCurrent() == NULL);

	ChainIteratorOf<Derivation*>
		j(&Beta::ClassDerivation->classDerivations);
	Verify(j.ReadAndNext() == Gamma::ClassDerivation);
	Verify(j.GetCurrent() == NULL);

	ChainIteratorOf<Derivation*>
		k(&Gamma::ClassDerivation->classDerivations);
	Verify(k.GetCurrent() == NULL);

	Verify(a.x == -1);
	Verify(b.x == -2);
	Verify(c.x == -3);

	//
	// Check basic method response
	//

	a.Method0();
	b.Method0();
	c.Method0();
	Verify(a.x == 0);
	Verify(b.x == 0);
	Verify(c.x == 0);

	a.Method1();
	b.Method1();
	c.Method1();
	Verify(a.x == 1);
	Verify(b.x == 6);
	Verify(c.x == 6);

	m.messageID = Beta::Method2MessageID;
	a.Dispatch(&m);
	b.Method2();
	c.Method2();
	Verify(a.x == 1);
	Verify(b.x == 2);
	Verify(c.x == 2);

	b.Method3();
	c.Method3();
	Verify(b.x == 3);
	Verify(c.x == 3);

	c.Method4();
	Verify(c.x == 4);

#endif
	return true;
}

