Files
firestorm/Gameleap/code/mw4/Libraries/Adept/Event.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

1018 lines
25 KiB
C++

//===========================================================================//
// File: event.cc //
// Project: MUNGA Brick: Event Manager //
// Contents: implementation details of event processing //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 10/19/94 JMA Initial coding. //
// 11/03/94 ECH Made compatible with BC4.0 //
// 11/05/94 JMA Made compatible with GNU C++ //
// 11/30/94 JMA Adapted to new style conventions //
// 12/01/94 JMA Made compatible with SGI CC //
//---------------------------------------------------------------------------//
// Copyright (C) 1994, Virtual World Entertainment, Inc. All Rights reserved //
// PROPRIETARY AND CONFIDENTIAL //
//===========================================================================//
#include "AdeptHeaders.hpp"
#include "EventStatistics.hpp"
#include "Network.hpp"
//#############################################################################
//########################### AbstractEvent #############################
//#############################################################################
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
AbstractEvent::AbstractEvent(
ClassData *class_data,
const Receiver::Message *message,
Time time
):
Plug(class_data)
{
Verify(message);
alarmTime = time;
//
//--------------------------------------------------------
// Allocate some memory to store the message parameters in
//--------------------------------------------------------
//
size_t long_size = (message->messageLength+3)>>2;
messageToSend = Cast_Pointer(Receiver::Message*, new long[long_size]);
Register_Object(messageToSend);
Mem_Copy(
messageToSend,
message,
message->messageLength,
long_size*sizeof(long)
);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
AbstractEvent::~AbstractEvent()
{
if (messageToSend)
{
Unregister_Pointer(messageToSend);
delete messageToSend;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
AbstractEvent::Process()
{
STOP(("AbstractEvent::Process should not be called!\n"));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
AbstractEvent::DumpData()
{
STOP(("AbstractEvent::DumpData should not be called!\n"));
}
//#############################################################################
//############################### Event #################################
//#############################################################################
MemoryBlock*
Event::AllocatedMemory = NULL;
Event::ClassData*
Event::DefaultData = NULL;
static DWORD
Event_Count;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Event::InitializeClass(
size_t block_count,
size_t block_delta
)
{
Verify(!AllocatedMemory);
AllocatedMemory =
new MemoryBlock(
sizeof(Event),
block_count,
block_delta,
"Event",
g_LibraryHeap
);
Register_Object(AllocatedMemory);
Verify(!DefaultData);
DefaultData =
new ClassData(
EventClassID,
"Adept::Event",
AbstractEvent::DefaultData
);
Register_Object(DefaultData);
Event_Count = 0;
#if !defined(NO_STATS)
AddStatistic("Queued Events", "events", gos_DWORD, &Event_Count, 0);
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Event::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
Unregister_Object(AllocatedMemory);
delete AllocatedMemory;
AllocatedMemory = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Event::Event(
Receiver *target,
const Receiver::Message *message,
Time time
):
AbstractEvent(DefaultData, message, time)
{
targetReceiver.Add(target);
Set_Statistic(Event_Count, Event_Count+1);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Event::~Event()
{
Set_Statistic(Event_Count, Event_Count-1);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Event::Repost(
EventQueue* queue,
Time new_time
)
{
Check_Object(this);
Check_Object(queue);
//
//-------------------------------------------
// Delete the link to the current event queue
//-------------------------------------------
//
STOP(("Not functional"));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Event::Process()
{
Check_Object(this);
Receiver *target = targetReceiver.GetCurrent();
if (target)
{
Check_Object(target);
target->Receive(this);
}
else
{
delete this;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Event::DumpData()
{
Check_Object(this);
#if defined(_ARMOR)
Receiver *target = targetReceiver.GetCurrent();
if (target)
{
Check_Object(target);
Receiver::ClassData *class_data = target->GetClassData();
Check_Object(class_data);
const Receiver::MessageEntry *entry =
target->GetMessageEntry(messageToSend->messageID);
Check_Object(entry);
Check_Pointer(entry->messageName);
SPEW((
GROUP_ADEPT_EVENT,
"%s::%s",
class_data->GetClassName(),
entry->messageName
));
}
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Event::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//#############################################################################
//########################### NetworkEvent ##############################
//#############################################################################
NetworkEvent::ClassData*
NetworkEvent::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
NetworkEvent::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
NetworkEventClassID,
"Adept::NetworkEvent",
AbstractEvent::DefaultData
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
NetworkEvent::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
NetworkEvent::NetworkEvent(
Connection *connection,
InBox *box,
EventStyle event_style,
const Receiver::Message *message,
Time time
):
AbstractEvent(DefaultData, message, time)
{
eventConnection = connection;
eventBox = box;
eventStyle = event_style;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
NetworkEvent::~NetworkEvent()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
NetworkEvent::Process()
{
Check_Object(this);
switch (eventStyle)
{
case SendStyle:
Check_Object(Network::GetInstance());
STOP(("Not implemented"));
// Network::GetInstance()->Send(messageToSend, hostID);
break;
case BroadcastStyle:
Check_Object(Network::GetInstance());
Network::GetInstance()->Broadcast(messageToSend);
break;
case ExclusiveBroadcastStyle:
Check_Object(Network::GetInstance());
Network::GetInstance()->ExclusiveBroadcast(messageToSend);
break;
}
Unregister_Object(this);
delete this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
NetworkEvent::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//#############################################################################
//####################### GeneralEventQueue ############################
//#############################################################################
//
// Shared Data Support
//
GeneralEventQueue::ClassData*
GeneralEventQueue::DefaultData = NULL;
GeneralEventQueue*
GeneralEventQueue::Instance = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void GeneralEventQueue::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
GeneralEventQueueClassID,
"Adept::GeneralEventQueue",
Plug::DefaultData
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void GeneralEventQueue::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
GeneralEventQueue::GeneralEventQueue(ClassData *class_data):
Plug(class_data)
{
priorityLevels = -1;
eventCount = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
GeneralEventQueue::~GeneralEventQueue()
{
pendingEvents.DeletePlugs();
timedEvents.DeletePlugs();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
GeneralEventQueue*
GeneralEventQueue::Make(
int priorities,
const char* count_trace_name,
const char* delay_trace_name
)
{
gos_PushCurrentHeap(g_Heap);
GeneralEventQueue *queue = new GeneralEventQueue[priorities];
Register_Object(queue);
queue->priorityLevels = priorities;
gos_PopCurrentHeap();
return queue;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
AbstractEvent*
GeneralEventQueue::Post(
Receiver *target,
const Receiver::Message *message,
Time time
)
{
Check_Object(this);
Check_Object(target);
Check_Object(message);
//
//------------------------------------------------------
// Create a new event, then insert it in the event queue
//------------------------------------------------------
//
Event *event = new Event(target, message, time);
Register_Object(event);
Enqueue(event);
return event;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
AbstractEvent*
GeneralEventQueue::SendEvent(
Connection *connection,
InBox *box,
const Receiver::Message *message,
Time when
)
{
Check_Object(this);
Check_Object(message);
NetworkEvent *event =
new NetworkEvent(
connection,
box,
NetworkEvent::SendStyle,
message,
when
);
Register_Object(event);
Enqueue(event);
return event;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
AbstractEvent*
GeneralEventQueue::BroadcastEvent(
InBox *box,
const Receiver::Message *message,
Time when
)
{
Check_Object(this);
Check_Object(message);
//
// HACK - What is a null network address?
//
NetworkEvent *event =
new NetworkEvent(
NULL,
box,
NetworkEvent::BroadcastStyle,
message,
when
);
Register_Object(event);
Enqueue(event);
return event;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
AbstractEvent*
GeneralEventQueue::ExclusiveBroadcastEvent(
InBox *box,
const Receiver::Message *message,
Time when
)
{
Check_Object(this);
Check_Object(message);
//
// HACK - What is a null network address?
//
NetworkEvent *event =
new NetworkEvent(
NULL,
box,
NetworkEvent::ExclusiveBroadcastStyle,
message,
when
);
Register_Object(event);
Enqueue(event);
return event;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
GeneralEventQueue::Enqueue(AbstractEvent *event)
{
Check_Object(event);
Check_Pointer(event->messageToSend);
int priority = event->messageToSend->messagePriority;
Verify(static_cast<unsigned>(priority) < priorityLevels);
//
//------------------------------------------------------------
// If this is not a timed event, stuff it in the pending queue
//------------------------------------------------------------
//
if (event->alarmTime == -1.0)
{
this[priority].pendingEvents.Add(event);
}
//
//----------------------------------------
// Otherwise, sort it into the timed queue
//----------------------------------------
//
else
{
ChainIteratorOf<AbstractEvent*>
timed_events(&this[priority].timedEvents);
timed_events.Last();
AbstractEvent* next_event = timed_events.GetCurrent();
//
//---------------------------------------------------------------------
// If the timed queue is empty, or if we are later than the last entry,
// just add the event to the end
//---------------------------------------------------------------------
//
if (!next_event || next_event->alarmTime <= event->alarmTime)
{
this[priority].timedEvents.Add(event);
}
//
//--------------------------------------------------------------------
// Find the event to insert before. If we run off the beginning, stop
// checking and set the iterator to the first event in the queue
//--------------------------------------------------------------------
//
else
{
do
{
timed_events.Previous();
next_event = timed_events.GetCurrent();
if (!next_event)
{
timed_events.First();
break;
}
} while (next_event->alarmTime > event->alarmTime);
//
//--------------------------------------------------------------------
// If we didn't run off the queue, we need to insert after the current
// event, so bump the iterator forward one event
//--------------------------------------------------------------------
//
if (next_event)
{
timed_events.Next();
}
//
//------------------------------------------------------------------
// Insert the new event ahead of where the iterator currently points
//------------------------------------------------------------------
//
timed_events.Insert(event);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
AbstractEvent*
GeneralEventQueue::PeekAtNextEvent(int min_priority)
{
Check_Object(this);
//
//--------------------------------------------------------------------------
// Start at the top of the priority queue, searching backwards until we find
// an available event or run off the minimum queue priority
//--------------------------------------------------------------------------
//
Verify(min_priority >= 0);
int priority = priorityLevels;
while (--priority >= min_priority)
{
//
//-------------------------------------------------------------------
// See if the first event in the timed queue is ready to go. If not,
// none of the other timed events will be ready to go either
//-------------------------------------------------------------------
//
ChainIteratorOf<AbstractEvent*>
timed_events(&this[priority].timedEvents);
AbstractEvent
*event = timed_events.GetCurrent();
if (event)
{
Check_Object(event);
if (event->alarmTime <= gos_GetElapsedTime())
{
return event;
}
}
//
//------------------------------
// Now look in the untimed queue
//------------------------------
//
ChainIteratorOf<AbstractEvent*>
events(&this[priority].pendingEvents);
event = events.GetCurrent();
if (event)
{
Check_Object(event);
return event;
}
}
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
GeneralEventQueue::IsPriorityEmpty(int priority)
{
Check_Object(this);
Verify(priority >= 0 && priority < priorityLevels);
ChainIteratorOf<AbstractEvent*> i(&this[priority].pendingEvents);
ChainIteratorOf<AbstractEvent*> j(&this[priority].timedEvents);
return !i.GetCurrent() && !j.GetCurrent();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
GeneralEventQueue::ProcessOneEvent(int min_priority)
{
Check_Object(this);
Verify(min_priority >= 0);
AbstractEvent *event=PeekAtNextEvent(min_priority);
if (event)
{
event->Process();
return true;
}
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
GeneralEventQueue::ProcessAllEvents(int min_priority)
{
Check_Object(this);
Verify(min_priority >= 0);
while (ProcessOneEvent(min_priority));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
GeneralEventQueue::FlushAllEvents(int max_priority)
{
Check_Object(this);
Verify(max_priority < priorityLevels);
//
//-----------------------------------------
// Make sure that max_priority is set right
//-----------------------------------------
//
if (max_priority < 0)
{
max_priority = priorityLevels - 1;
}
//
//---------------------------------------------------------------------
// Step through each of the priority queues and delete any events found
// within
//---------------------------------------------------------------------
//
for (int priority=max_priority; priority>=0; --priority)
{
//
//---------------------------------------
// Delete the events from the timed queue
//---------------------------------------
//
ChainIteratorOf<AbstractEvent*> i(&this[priority].timedEvents);
AbstractEvent *event;
while ((event = i.ReadAndNext()) != NULL)
{
Unregister_Object(event);
delete event;
}
//
//-----------------------------------------
// Delete the events from the regular queue
//-----------------------------------------
//
ChainIteratorOf<AbstractEvent*> j(&this[priority].pendingEvents);
while ((event = j.ReadAndNext()) != NULL)
{
Unregister_Object(event);
delete event;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
GeneralEventQueue::FlushMatchingEvents(
Receiver::MessageID target_message,
int max_priority
)
{
Check_Object(this);
Verify(max_priority < priorityLevels);
//
//-----------------------------------------
// Make sure that max_priority is set right
//-----------------------------------------
//
if (max_priority < 0)
{
max_priority = priorityLevels - 1;
}
//
//---------------------------------------------------------------------
// Step through each of the priority queues and delete any events found
// within
//---------------------------------------------------------------------
//
for (int p=max_priority; p>=0; --p)
{
//
//-------------------------------------------
// Delete events from the regular queue first
//-------------------------------------------
//
ChainIteratorOf<AbstractEvent*> i(&this[p].pendingEvents);
AbstractEvent *event;
while ((event = i.ReadAndNext()) != NULL)
{
//
//------------------------------
// Make sure the message matches
//------------------------------
//
if (
target_message == Receiver::AnyMessageID
|| target_message == event->messageToSend->messageID
)
{
Unregister_Object(event);
delete event;
}
}
//
//-----------------------------------
// Delete events from the timed queue
//-----------------------------------
//
ChainIteratorOf<AbstractEvent*> j(&this[p].timedEvents);
while ((event = j.ReadAndNext()) != NULL)
{
//
//------------------------------
// Make sure the message matches
//------------------------------
//
if (
target_message == Receiver::AnyMessageID
|| target_message == event->messageToSend->messageID
)
{
Unregister_Object(event);
delete event;
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
GeneralEventQueue::DumpEventQueue()
{
Check_Object(this);
//
//----------------------------------------------------------------------
// Step through each of the priority queues and display any events found
// within
//----------------------------------------------------------------------
//
unsigned total_count = 0;
for (int priority=priorityLevels - 1; priority>=0; --priority)
{
SPEW((GROUP_ADEPT_EVENT, "EventQueue priority %d", priority));
SPEW((
GROUP_ADEPT_EVENT,
"--------------------------------------------------------------"
));
ChainIteratorOf<AbstractEvent*> i(&this[priority].pendingEvents);
AbstractEvent *event;
size_t count=0;
while ((event = i.ReadAndNext()) != NULL)
{
++count;
event->DumpData();
}
SPEW((
GROUP_ADEPT_EVENT,
"%d priority %d events",
count,
priority
));
count = 0;
ChainIteratorOf<AbstractEvent*> j(&this[priority].timedEvents);
while ((event = j.ReadAndNext()) != NULL)
{
++count;
event->DumpData();
}
SPEW((
GROUP_ADEPT_EVENT,
"%d priority %d timed events",
count,
priority
));
total_count += count;
}
SPEW((
GROUP_ADEPT_EVENT, "%d total events in queues", total_count));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
GeneralEventQueue::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//#############################################################################
//############################ EventQueue ###############################
//#############################################################################
//
// Shared Data Support
//
EventQueue::ClassData*
EventQueue::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
EventQueue::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
EventQueueClassID,
"Adept::EventQueue",
GeneralEventQueue::DefaultData
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
EventQueue::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
EventQueue::EventQueue():
GeneralEventQueue(DefaultData)
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
EventQueue::~EventQueue()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
EventQueue*
EventQueue::Make(
int priorities,
const char* trace_name,
const char* delay_trace_name
)
{
gos_PushCurrentHeap(g_Heap);
EventQueue *queue = new EventQueue[priorities];
Register_Object(queue);
queue->priorityLevels = priorities;
gos_PopCurrentHeap();
return queue;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
EventQueue::ProcessMatchingEvents(
Receiver *receiver,
Receiver::MessageID message_ID
)
{
Check_Object(this);
Check_Object(receiver);
//
//----------------------------------------------------------------
// Step through each of the priority queues and process any events
// found within
//----------------------------------------------------------------
//
for (int p=priorityLevels-1; p>=0; --p)
{
Event *event;
AbstractEvent *abstract_event;
ChainIteratorOf<AbstractEvent*> i(&this[p].pendingEvents);
while ((abstract_event = i.ReadAndNext()) != NULL)
{
Check_Object(abstract_event);
event = Cast_Object(Event*, abstract_event);
//
//------------------------------
// Make sure the message matches
//------------------------------
//
if (
(event->targetReceiver.GetCurrent() == receiver) &&
(message_ID == Receiver::AnyMessageID ||
message_ID == event->messageToSend->messageID)
)
{
event->Process();
}
}
ChainIteratorOf<AbstractEvent*> j(&this[p].timedEvents);
while ((abstract_event = j.ReadAndNext()) != NULL)
{
Check_Object(abstract_event);
event = Cast_Object(Event*, abstract_event);
//
//------------------------------
// Make sure the message matches
//------------------------------
//
if (
(event->targetReceiver.GetCurrent() == receiver) &&
(message_ID == Receiver::AnyMessageID ||
message_ID == event->messageToSend->messageID)
)
{
event->Process();
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
EventQueue::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}