Files
RP411/MUNGA/RECEIVER.h
T
CydandClaude Opus 4.8 4abbf8879f Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet',
built on the MUNGA engine and its L4 (Win32/DirectX) platform layer:

- MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend
- RP / RP_L4: Red Planet game logic and Win32 application
- DivLoader, Setup1: asset loader and installer project
- lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies

Removed stale Subversion metadata and added .gitignore/.gitattributes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 07:59:51 -05:00

547 lines
13 KiB
C++

#pragma once
#include "node.h"
#include "chain.h"
#include "memblock.h"
#include "memstrm.h"
class Receiver__SharedData;
class Receiver__InheritanceSet;
struct Receiver__HandlerEntry;
class Receiver__MessageHandlerSet;
class Receiver__Message;
class Receiver__DynamicMessage;
class Derivation;
class Event;
class DynamicMemoryStream;
class MessageTap;
//##########################################################################
//########################## Receiver ################################
//##########################################################################
//
// It is suggested that calls to methods meant to be serviced by a receiver
// be built through inline functions in the derived class, rather than
// having to build the parameter block in the scope of the caller. Letting
// the inline code build the parameter block is much cleaner, and allows the
// message code numbers to be held inside the derived class, further
// protecting against calling methods for objects not in a proper derivation
// chain.
//
class Receiver:
public Node
{
//##########################################################################
// Shared Data Support
//
public:
typedef Receiver__SharedData SharedData;
SharedData*
GetSharedData() const;
static Derivation* GetClassDerivations();
Derivation*
GetDerivation() const;
static SharedData DefaultData;
Logical
IsDerivedFrom(Derivation& parent) const;
Logical
IsDerivedFrom(const char* parent) const;
protected:
const SharedData* sharedData;
//##########################################################################
// Construction and Destruction Support
//
protected:
Receiver(
ClassID class_ID,
SharedData &shared_data
):
Node(class_ID),
sharedData(&shared_data)
{}
Receiver(
PlugStream *stream,
SharedData &shared_data
):
Node(stream),
sharedData(&shared_data)
{}
//##########################################################################
// Messaging Support
//
public:
typedef Receiver__Message Message;
typedef Receiver__DynamicMessage DynamicMessage;
typedef Receiver__InheritanceSet InheritanceSet;
typedef Receiver__HandlerEntry HandlerEntry;
typedef Receiver__MessageHandlerSet MessageHandlerSet;
typedef void (Receiver::*Handler)(const Message*);
typedef Enumeration MessageID;
enum {
AnyMessageID=0,
WatcherChangedMessageID,
LoadResourceFinishedMessageID,
NextMessageID
};
static const Handler NullHandler;
void
Receive(Message *What);
virtual void
Dispatch(Message *What)
{Receive(What);}
void
DefaultMessageHandler(Message*);
typedef void (Receiver::*ScanCallback)(
Receiver::Message *message,
Receiver *receiver
);
MessageTap*
MakeMessageTap(
Derivation *derivation,
ScanCallback callback
);
MessageTap*
MakeMessageTap(
Derivation *derivation,
ScanCallback callback,
Receiver::MessageID matching_message,
Receiver *match_receiver
);
protected:
static const HandlerEntry MessageHandlerEntries[];
// swapping the commented line for the following one due to inconsitincies
// in the order of initialization for static member variables
//static MessageHandlerSet MessageHandlers;
static MessageHandlerSet& GetMessageHandlers();
//##########################################################################
// Event Support
//
public:
virtual void
Receive(Event *event);
void
FlushEvents(int max_priority=-1);
void
FlushMatchingEvents(
MessageID target_message,
int max_priority=-1
);
void
ProcessDeferredQueue();
//##########################################################################
// Test Support
//
public:
static Logical
TestClass();
Logical
TestInstance() const;
};
//##########################################################################
//###################### Receiver::Message ###########################
//##########################################################################
class Receiver__Message
{
public:
#if defined(USE_SIGNATURE)
friend int
Is_Signature_Bad(const volatile Receiver__Message *);
#endif
size_t
messageLength;
Receiver::MessageID
messageID;
enum {
ReliableBit,
NextBit
};
enum {
ReliableFlag = 1 << ReliableBit
};
LWord
messageFlags;
Receiver__Message(
Receiver::MessageID id,
size_t message_length
):
messageID(id),
messageLength(message_length),
messageFlags(ReliableFlag) // HACK
{}
Logical
TestInstance() const;
};
//##########################################################################
//################### Receiver::DynamicMessage #######################
//##########################################################################
class Receiver__DynamicMessage:
public DynamicMemoryStream
{
public:
Receiver__DynamicMessage()
{}
Receiver__DynamicMessage(
void *stream_start,
size_t stream_size,
size_t initial_offset=0
):
DynamicMemoryStream(stream_start, stream_size, initial_offset)
{}
Receiver__DynamicMessage(
Receiver::MessageID message_ID,
size_t size = sizeof(Receiver::Message)
);
Receiver::Message*
GetMessagePointer()
{Check(this); return Cast_Object(Receiver::Message*, streamStart);}
protected:
MemoryStream&
WriteBytes(
const void *ptr,
size_t number_of_bytes
);
};
//##########################################################################
//#################### ReceiverDataMessageOf #########################
//##########################################################################
template <class T> class ReceiverDataMessageOf:
public Receiver::Message
{
public:
T
dataContents;
ReceiverDataMessageOf(
Receiver::MessageID id,
size_t message_length,
const T& data
):
Receiver::Message(id, message_length),
dataContents(data)
{}
};
//##########################################################################
//######################### MessageTap ###############################
//##########################################################################
class MessageTap:
public Plug
{
//##########################################################################
// MessageTap Functionality
//
public:
MessageTap(
Derivation *derivation,
Receiver *client,
Receiver::ScanCallback callback
);
MessageTap(
Derivation *derivation,
Receiver *client,
Receiver::ScanCallback callback,
Receiver::MessageID matching_message,
Receiver *match_receiver
);
private:
Receiver::ScanCallback scanCallback;
Receiver* clientReceiver;
Receiver* matchingReceiver;
Receiver::MessageID matchingMessageID;
public:
void
Scan(
Receiver *receiver,
Receiver::Message *message
);
//##########################################################################
// Memory Allocation
//
private:
static MemoryBlock* GetAllocatedMemory();
public:
void* operator new(size_t) { return GetAllocatedMemory()->New(); }
void operator delete(void *where) { GetAllocatedMemory()->Delete(where); }
//##########################################################################
// Test support
//
public:
Logical
TestInstance() const;
static Logical
TestClass();
};
//##########################################################################
//################## Receiver::InheritanceSet ########################
//##########################################################################
//
// NOTE: An InheritanceSet generated for a class should only be inherited by
// other classes derived from that base class. If this is not done,
// SEVERE run-time weirdness will happen
//
class Receiver__InheritanceSet SIGNATURED
{
public:
Logical
TestInstance() const;
Enumeration
GetEntryCount()
{Check(this); return entryCount;}
protected:
Enumeration
entryCount;
Receiver__InheritanceSet()
{}
~Receiver__InheritanceSet()
{}
};
//##########################################################################
//################### Receiver::HandlerEntry #########################
//##########################################################################
struct Receiver__HandlerEntry
{
Enumeration
entryID;
const char*
entryName;
Receiver::Handler
entryHandler;
};
#define MESSAGE_ENTRY(class,message)\
{\
class::message##MessageID,\
#message,\
(Receiver::Handler)&class::message##MessageHandler\
}
//##########################################################################
//################# Receiver::MessageHandlerSet ######################
//##########################################################################
class Receiver__MessageHandlerSet:
public Receiver__InheritanceSet
{
//##########################################################################
// Constructors and Destructors
//
public:
Receiver__MessageHandlerSet(Receiver::MessageID count, const Receiver::HandlerEntry handler_table[], const Receiver::MessageHandlerSet &inheritance) { Build(count, handler_table, &inheritance); }
Receiver__MessageHandlerSet(Receiver::MessageID count, const Receiver::HandlerEntry handler_table[]) { Build(count, handler_table, NULL); }
Receiver__MessageHandlerSet(const Receiver::MessageHandlerSet& source) { Build(0, NULL, &source); }
Receiver__MessageHandlerSet()
{
messageHandlers = NULL;
entryCount = 0;
}
~Receiver__MessageHandlerSet();
protected:
void
Build(
Receiver::MessageID count,
const Receiver::HandlerEntry handler_table[],
const Receiver::MessageHandlerSet *inheritance
);
//##########################################################################
// HandlerSet Functionality
//
public:
static const Receiver::MessageHandlerSet
NullSet;
Receiver::Handler Find(Receiver::MessageID message) const
{
Check(this);
Verify(message > 0);
return (message<=entryCount) ? messageHandlers[message-1].entryHandler : Receiver::NullHandler;
}
const Receiver::HandlerEntry*
Find(const char* name) const;
const char *
GetName(Receiver::MessageID message) const
{
Check(this);
return (message<=entryCount)
? messageHandlers[message-1].entryName
: NULL;
}
protected:
Receiver::HandlerEntry* messageHandlers;
//##########################################################################
// Test Support
//
public:
static Logical
TestClass();
};
//##########################################################################
//########################## Derivation ##############################
//##########################################################################
class Derivation:
public Node
{
friend class Receiver;
//##########################################################################
// Construction and Destruction
//
public:
Derivation(char *who);
Derivation(Derivation *parent,char *who);
char *className;
//##########################################################################
// Messagetap support
//
private:
Derivation(Derivation& copy);
ChainOf<MessageTap*>
activeTaps;
public:
void
AppendMessageTap(MessageTap* tap);
Logical
IsDescendedFrom(Derivation& parent);
Logical
IsDescendedFrom(const char* parent);
//##########################################################################
// Inheritance Registration Support
//
private:
ChainOf<Derivation*>
classDerivations;
void
AppendDerivation(Derivation* child)
{Check(this); classDerivations.Add(child);}
//##########################################################################
// Test Support
//
public:
static Logical
TestClass();
};
//##########################################################################
//################### Receiver::SharedData ##########################
//##########################################################################
class Receiver__SharedData SIGNATURED
{
public:
Receiver__SharedData(
Derivation* derivation,
Receiver::MessageHandlerSet &handler
):
derivedClasses(derivation),
activeMessageHandlers(&handler)
{
//activeMessageHandlers = &activeMessageHandlersInstance;
}
Derivation *derivedClasses;
Receiver::MessageHandlerSet *activeMessageHandlers;
Logical
TestInstance() const;
//private:
// Receiver::MessageHandlerSet activeMessageHandlersInstance;
};
inline Receiver::SharedData*
Receiver::GetSharedData() const
{Check(this); return Cast_Object(SharedData*,sharedData);}
inline Derivation*
Receiver::GetDerivation() const
{Check(this); return GetSharedData()->derivedClasses;}
inline Logical
Receiver::IsDerivedFrom(Derivation& parent) const
{return sharedData->derivedClasses->IsDescendedFrom(parent);}
inline Logical
Receiver::IsDerivedFrom(const char* parent) const
{Check(this); return GetDerivation()->IsDescendedFrom(parent);}
inline MessageTap*
Receiver::MakeMessageTap(
Derivation *derivation,
ScanCallback callback
)
{Check(this); return new MessageTap(derivation, this, callback);}
inline MessageTap*
Receiver::MakeMessageTap(
Derivation *derivation,
ScanCallback callback,
Receiver::MessageID matching_message,
Receiver *match_receiver
)
{
Check(this);
return new MessageTap(
derivation,
this,
callback,
matching_message,
match_receiver
);
}