//===========================================================================//
// File:	event.tst                                                           //
// Project: MUNGA           Brick: Dynamic Dispatch                          //
// Contents: Verify stuff for Event class                                      //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 11/02/94  JMA  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1994, Virtual World Entertainment, Inc. All Rights reserved //
//                      PROPRIETARY AND CONFIDENTIAL                         //
//===========================================================================//

#include "AdeptHeaders.hpp"

#include "receiver_test.hpp"

bool
	EventQueue::TestClass()
{
	SPEW((GROUP_STUFF_TEST, "Starting EventQueue test..."));

	//
	// Construct Queues
	//
	EventQueue
		*p = EventQueue::Make(5),
		*q = new EventQueue;
	Register_Object(q);

	Verify(p->priorityLevels == 5);
	Verify(q->priorityLevels == 1);

	//
	// Verify how a single priority queue works
	//
	Receiver::Message
		m(
			Alpha::Method0MessageID,
			sizeof(Receiver::Message),
			0,
			Receiver::Message::DefaultFlags
		),
		n(
			Alpha::Method1MessageID,
			sizeof(Receiver::Message),
			0,
			Receiver::Message::DefaultFlags
		);
	Alpha
		a,b;
	Event
		*event;

	q->Post(&a, &m);
	Verify(a.x == -1);

	event = q->PeekAtNextEvent();
	Verify(event);
	Verify(event->targetReceiver.GetCurrent() == &a);
	Verify(event->messageToSend);
	Verify(a.x == -1);
	STOP(("Not implemented"));
#if 0
	PlugIteratorOf<Event*>
		i(&a);
	Verify(i.GetCurrent() == event);

	event->Process();
	Verify(a.x == 0);
	Verify(!q->PeekAtNextEvent());
#endif

	//
	// Verify multiple events
	//
	a.x = -1;
	q->Post(&a, &m);
	event = q->PeekAtNextEvent();
	q->Post(&a, &n);
	Verify(q->PeekAtNextEvent() == event);
	Verify(q->ProcessOneEvent());
	Verify(a.x == 0);
	Verify(q->ProcessOneEvent());
	Verify(a.x == 1);
	Verify(!q->ProcessOneEvent());

#if 0
	//
	// Verify timed messages
	//
	a.x = -1;
	Time t = Now();
	t += 0.5f;
	q->Post(&a, &m, t);
	SystemTime t2 = t;
	t2 += 0.1f;
	while (!q->ProcessOneEvent())
	{
		Verify(Now() < t2);
	}
	Scalar f = (Now() - t).GetSeconds();
	Verify(Abs(f) < 0.06f);
	Verify(a.x == 0);
	Verify(!q->PeekAtNextEvent());
#endif

	//
	// Verify multi-priority Queues
	//
	a.x = -1;
	m.messagePriority = 2;
	p->Post(&a, &m);
	event = p->PeekAtNextEvent();
	Verify(event);
	n.messagePriority = 3;
	p->Post(&a, &n);
	Verify(event != p->PeekAtNextEvent());

	p->ProcessOneEvent(3);
	Verify(a.x == 1);
	event = p->PeekAtNextEvent(3);
	Verify(!event);
	event = p->PeekAtNextEvent();
	Verify(event);
	Verify(event->targetReceiver.GetCurrent() == &a);
	p->ProcessOneEvent();
	Verify(a.x == 0);
	Verify(!p->PeekAtNextEvent());

	//
	// Verify Reposting
	//
	a.x = -1;
	m.messagePriority = 0;
	q->Post(&a, &m);
	event = q->PeekAtNextEvent();
	event->messageToSend->messagePriority = 2;
	event->Repost(p);
	Verify(!q->PeekAtNextEvent());
	Verify(!p->PeekAtNextEvent(3));
	Verify(p->PeekAtNextEvent(2));
	p->ProcessOneEvent();
	Verify(!p->PeekAtNextEvent());
	Verify(a.x == 0);

	//
	// Verify destroying a receiver
	//
	Alpha *a2 = new Alpha;
	Register_Object(a2);
	n.messagePriority = 1;
	p->Post(a2, &n);
	Verify(p->PeekAtNextEvent());
	Unregister_Object(a2);
	delete a2;
	Verify(!p->PeekAtNextEvent());

	//
	// Time test the flushing functions
	//
	n.messagePriority = 0;
	q->Post(&a, &n);
	q->Post(&a, &m);
	a.FlushMatchingEvents(Alpha::Method1MessageID);
	Verify(q->PeekAtNextEvent()->messageToSend->messageID == Alpha::Method0MessageID);
	a.FlushEvents();
	Verify(!q->PeekAtNextEvent());

	q->Post(&a, &n);
	q->Post(&b, &m);
	q->FlushMatchingEvents(Alpha::Method1MessageID);
	Verify(q->PeekAtNextEvent()->messageToSend->messageID == Alpha::Method0MessageID);
	q->FlushAllEvents();
	Verify(!q->PeekAtNextEvent());

	//
	// Get rid of the queues
	//
	Unregister_Object(p);
	delete[] p;

	Unregister_Object(q);
	delete q;
	return true;
}
