Files
TeslaRel410/CODE/RP/MUNGA/HOSTMGR.CPP
T
CydandClaude Fable 5 fdd9ac9d97 Initial import: Tesla Release 4.10 (Tesla:BattleTech & Tesla:Red Planet)
Archival snapshot of the Virtual World Entertainment Tesla cockpit
software, 1994-1996: MUNGA engine and L4 pod layer source (Borland
C++ 5.0), BT/RP game code, and game content (models, audio, maps,
gauges, Division renderer data). Includes third-party libraries:
Division dVS/DPL graphics, HMI SOS audio, WATTCP networking.

Files are preserved byte-for-byte (.gitattributes disables all
line-ending conversion). README.md documents the layout, target
hardware, and toolchain.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 13:21:58 -05:00

734 lines
19 KiB
C++

//===========================================================================//
// File: hostmgr.cpp //
// Project: MUNGA Brick: Connection Library //
// Contents: Interface specification for base Host class //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 10/28/94 ECH Initial coding. //
// 11/03/94 ECH Develop to munga spec //
// 11/29/94 JMA Moved EntityID to entity.cc //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include <munga.hpp>
#pragma hdrstop
#if !defined(HOSTMGR_HPP)
# include <hostmgr.hpp>
#endif
#if !defined(INTEREST_HPP)
# include <interest.hpp>
#endif
#if !defined(APP_HPP)
#include <app.hpp>
#endif
#if !defined(ENTITY_HPP)
#include <entity.hpp>
#endif
//#############################################################################
//######################### HostManager #################################
//#############################################################################
//
// HACK - EntitySocketHashSize should come from somewhere else
//
const CollectionSize EntitySocketHashSize = 500;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// HostManager data
//
HostManager::SharedData
HostManager::DefaultData(
HostManager::ClassDerivations,
HostManager::MessageHandlers
);
Derivation
HostManager::ClassDerivations(
NetworkClient::ClassDerivations,
"HostManager"
);
const Receiver::HandlerEntry
HostManager::MessageHandlerEntries[]=
{
{
HostManager::NewHostMessageID,
"NewHost",
(HostManager::Handler)&Receiver::DefaultMessageHandler // HACK
},
{
HostManager::HostUpdateMessageID,
"HostUpdate",
(HostManager::Handler)&Receiver::DefaultMessageHandler // HACK
},
{
HostManager::EntityTransferOwnershipMessageID,
"EntityTransferOwnership",
(HostManager::Handler)&HostManager::EntityTransferOwnershipHandler
},
{
HostManager::EntityNewOwnershipMessageID,
"EntityNewOwnership",
(HostManager::Handler)&HostManager::EntityNewOwnershipHandler
}
};
Receiver::MessageHandlerSet
HostManager::MessageHandlers(
ELEMENTS(HostManager::MessageHandlerEntries),
HostManager::MessageHandlerEntries,
Receiver::MessageHandlers
);
//
//#############################################################################
// HostManager
//#############################################################################
//
HostManager::HostManager():
NetworkClient(HostManagerClassID, DefaultData, HostManagerClientID),
remoteHostSocket(NULL, True),
allHostSocket(NULL, True),
entityIndexSocket(EntitySocketHashSize, NULL, True)
{
localHost = NULL;
allHostIterator = NULL;
}
//
//#############################################################################
//#############################################################################
//
HostManager::~HostManager()
{
if (allHostIterator != NULL)
{
Unregister_Object(allHostIterator);
delete allHostIterator;
allHostIterator = NULL;
}
Verify(localHost == NULL);
#if DEBUG_LEVEL>0
{
TableIteratorOf<Host*, HostID> iterator(&remoteHostSocket);
Check(&iterator);
Verify(iterator.GetSize() == 0);
}
#endif
#if DEBUG_LEVEL>0
{
HashIteratorOf<Entity*, EntityID> iterator(&entityIndexSocket);
Check(&iterator);
Verify(iterator.GetSize() == 0);
}
#endif
}
//
//#############################################################################
//#############################################################################
//
Logical
HostManager::TestInstance() const
{
if (!IsDerivedFrom(ClassDerivations))
{
return False;
}
if (localHost != NULL)
{
Check(localHost)
}
if (allHostIterator != NULL)
{
Check(allHostIterator)
}
Check(&remoteHostSocket);
Check(&allHostSocket);
Check(&lastEntityID);
Check(&entityIndexSocket);
return True;
}
//
//#############################################################################
// Shutdown
//#############################################################################
//
void
HostManager::Shutdown()
{
Check(this);
#if 0 // HACK - Partial Implementation
//
//--------------------------------------------------------------------------
// For (each transferrable entity)
//--------------------------------------------------------------------------
//
//
// Find new host for ownership
//
//
// Send transfer entity ownership to that host
//
#else
//
//--------------------------------------------------------------------------
// Delete all of the entities
//--------------------------------------------------------------------------
//
if (localHost != NULL)
{
Check(localHost);
Host::AllEntityIterator iterator(localHost);
Check(&iterator);
iterator.DeletePlugs();
}
#endif
}
//
//#############################################################################
// AdoptLocalHost
//#############################################################################
//
void
HostManager::AdoptLocalHost(Host *local_host)
{
Check(this);
Check(local_host);
//
//--------------------------------------------------------------------------
// Verify that the local host is currently unassigned and then assign it
//--------------------------------------------------------------------------
//
Verify(lastEntityID == EntityID::Null);
Verify(localHost == NULL);
localHost = local_host;
EntityID entity_ID(local_host->GetHostID());
lastEntityID = entity_ID;
//
//--------------------------------------------------------------------------
// Add the local host to the all host socket
//--------------------------------------------------------------------------
//
allHostSocket.AddValue(local_host, local_host->GetHostID());
}
//
//#############################################################################
// OrphanLocalHost
//#############################################################################
//
Host*
HostManager::OrphanLocalHost()
{
Check(this);
//
//--------------------------------------------------------------------------
// Unassign the local host
//--------------------------------------------------------------------------
//
Host *local_host = localHost;
localHost = NULL;
lastEntityID = EntityID::Null;
//
//--------------------------------------------------------------------------
// Remove the local host from the all host socket
//--------------------------------------------------------------------------
//
if (local_host != NULL)
{
Check(local_host);
PlugIterator remover(local_host);
remover.RemoveSocket(&allHostSocket);
}
return local_host;
}
//
//#############################################################################
// AdoptRemoteHost
//#############################################################################
//
void
HostManager::AdoptRemoteHost(Host *remote_host)
{
Check(this);
Check(remote_host);
//
//--------------------------------------------------------------------------
// Add to the remote and all host socket
//--------------------------------------------------------------------------
//
remoteHostSocket.AddValue(remote_host, remote_host->GetHostID());
allHostSocket.AddValue(remote_host, remote_host->GetHostID());
}
//
//#############################################################################
// OrphanRemoteHost
//#############################################################################
//
void
HostManager::OrphanRemoteHost(Host *remote_host)
{
Check(this);
Check(remote_host);
//
//--------------------------------------------------------------------------
// Remove from the remote and all host socket
//--------------------------------------------------------------------------
//
{
PlugIterator remover(remote_host);
remover.RemoveSocket(&remoteHostSocket);
}
{
PlugIterator remover(remote_host);
remover.RemoveSocket(&allHostSocket);
}
}
//
//#############################################################################
// GetLocalHostID
//#############################################################################
//
HostID
HostManager::GetLocalHostID()
{
Check(this);
Check(localHost);
return localHost->GetHostID();
}
//
//#############################################################################
// GetRemoteHost
//#############################################################################
//
Host*
HostManager::GetRemoteHost(HostID host_ID)
{
Check(this);
Verify(host_ID >= FirstLegalHostID);
return remoteHostSocket.Find(host_ID);
}
//
//#############################################################################
// GetConsoleHost
//#############################################################################
//
Host*
HostManager::GetConsoleHost()
{
Check(this);
Host *host;
TableIteratorOf<Host*, HostID> iterator(&remoteHostSocket);
Check(&iterator);
while ((host = iterator.ReadAndNext()) != NULL)
{
Check(host);
if (host->GetHostType() == ConsoleHostType)
return host;
}
return NULL;
}
//
//#############################################################################
// FindHost
//#############################################################################
//
Host*
HostManager::FindHost(NetworkAddress net_address)
{
Check(this);
Host *host;
TableIteratorOf<Host*, HostID> iterator(&allHostSocket);
Check(&iterator);
while ((host = iterator.ReadAndNext()) != NULL)
{
Check(host);
if (host->GetNetworkAddress() == net_address)
{
return host;
}
}
return NULL;
}
//
//#############################################################################
// MakeUniqueEntityID
//#############################################################################
//
EntityID
HostManager::MakeUniqueEntityID()
{
Check(this);
Verify(lastEntityID != EntityID::Null);
return (lastEntityID += 1);
}
//
//#############################################################################
// NotifyOfEntityCreation
//#############################################################################
//
void
HostManager::NotifyOfEntityCreation(
Entity *entity,
Entity::MakeMessage *creation_message
)
{
Check(this);
Check(entity);
Check(creation_message);
//
//--------------------------------------------------------------------------
// The host keeps track of all entities
//--------------------------------------------------------------------------
//
Check(localHost);
localHost->AddEntity(entity);
//
//--------------------------------------------------------------------------
// Link the entity to our index
//--------------------------------------------------------------------------
//
Verify(entity->GetEntityID() != EntityID::Null);
Check(&entityIndexSocket);
entityIndexSocket.AddValue(entity, entity->GetEntityID());
//
//--------------------------------------------------------------------------
// Call interest manager
//--------------------------------------------------------------------------
//
Check(application);
Check(application->GetInterestManager());
application->GetInterestManager()->NotifyOfEntityCreation(
entity,
creation_message
);
}
//
//#############################################################################
// NotifyOfReplacementEntityCreation
//#############################################################################
//
void
HostManager::NotifyOfReplacementEntityCreation(
Entity*,
EntityID,
ClassID,
LWord
)
{
Fail("HostManager::NotifyOfReplacementEntityCreation - under construction");
}
//
//#############################################################################
// NotifyOfEntityDestruction
//#############################################################################
//
void
HostManager::NotifyOfEntityDestruction(Entity *entity)
{
//
//--------------------------------------------------------------------------
// Perform any additional processing here...
//--------------------------------------------------------------------------
//
//
//--------------------------------------------------------------------------
// Notify interest manager of the destruction
//--------------------------------------------------------------------------
//
Check(application);
Check(application->GetInterestManager());
application->GetInterestManager()->NotifyOfEntityDestruction(entity);
}
//
//#############################################################################
// IdentifyNewMapEntityHost
//#############################################################################
//
HostID
HostManager::IdentifyNewMapEntityHost(
EntityID
)
{
Check(this);
//
//--------------------------------------------------------------------------
// HACK - Partial Implementation, since the entity IDs are not yet
// precomputed several assumptions are made. 1) The map stream read by each
// pilot is identical. 2) All of the hosts are connected at the point that
// the stream is read. => Therefore, it is easy to allocate the entities to
// each host.
//--------------------------------------------------------------------------
//
//
//--------------------------------------------------------------------------
// Verify that legal map entity hosts exist
//--------------------------------------------------------------------------
//
#if DEBUG_LEVEL>0
{
TableIteratorOf<Host*, HostID> iterator(&allHostSocket);
Host *host;
CollectionSize legal_map_entity_hosts = 0;
while ((host = iterator.ReadAndNext()) != NULL)
{
if (host->GetHostType() == GameMachineHostType)
{
legal_map_entity_hosts++;
}
}
Verify(legal_map_entity_hosts > 0);
}
#endif
//
//--------------------------------------------------------------------------
// Check the host iterator
//--------------------------------------------------------------------------
//
if (allHostIterator == NULL)
{
allHostIterator = new TableIteratorOf<Host*, HostID>(&allHostSocket);
Register_Object(allHostIterator);
}
Check(allHostIterator);
//
//--------------------------------------------------------------------------
// Get a legal map entity host
//--------------------------------------------------------------------------
//
Host *map_entity_host;
Logical is_legal_map_entity_host = False;
do
{
if ((map_entity_host = allHostIterator->GetCurrent()) == NULL)
{
allHostIterator->First();
map_entity_host = allHostIterator->GetCurrent();
}
Check(map_entity_host);
if (map_entity_host->GetHostType() == GameMachineHostType)
{
is_legal_map_entity_host = True;
}
else
{
allHostIterator->Next();
}
}
while (!is_legal_map_entity_host);
//
//--------------------------------------------------------------------------
// Move to the next host
//--------------------------------------------------------------------------
//
allHostIterator->Next();
//
//--------------------------------------------------------------------------
// Return the map entity host ID
//--------------------------------------------------------------------------
//
Check(map_entity_host);
Verify(map_entity_host->GetHostType() == GameMachineHostType);
Verify(map_entity_host->GetHostID() != NullHostID);
return map_entity_host->GetHostID();
}
//
//#############################################################################
// EntityTransferOwnership
//#############################################################################
//
void
HostManager::EntityTransferOwnershipHandler(
EntityTransferOwnershipMessage*
)
{
#if 0
//
// Find replicant for this entity
//
//
// If (replicant found)
//
//
// Morph the replicant into the master replicant
//
//
// If (the replicant was not found)
//
//
// Make a transferred master entity
//
//
// Broadcast new entity ownership
//
#else
Fail("HostManager::EntityTransferOwnershipHandler - under construction");
#endif
}
//
//#############################################################################
// EntityNewOwnership
//#############################################################################
//
void
HostManager::EntityNewOwnershipHandler(
EntityNewOwnershipMessage*
)
{
#if 0
//
// If (this host is the owner host)
//
//
// Return
//
//
// Find the replicant for this entity
//
//
// If (found the replicant)
//
//
// Point it at the new owner
//
#else
Fail("HostManager::EntityNewOwnershipHandler - under construction");
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~ HostManager__AllEntityIterator ~~~~~~~~~~~~~~~~~~~~~
HostManager__AllEntityIterator::HostManager__AllEntityIterator(
HostManager *host_manager
):
Host__AllEntityIterator(host_manager->localHost)
{
}
HostManager__AllEntityIterator::~HostManager__AllEntityIterator()
{
}
//~~~~~~~~~~~~~~~~~~ HostManager__DynamicMasterEntityIterator ~~~~~~~~~~~~~~~~~
HostManager__DynamicMasterEntityIterator::
HostManager__DynamicMasterEntityIterator(
HostManager *host_manager
):
Host__DynamicMasterEntityIterator(host_manager->localHost)
{
}
HostManager__DynamicMasterEntityIterator::
~HostManager__DynamicMasterEntityIterator()
{
}
//~~~~~~~~~~~~~~~~~ HostManager__DynamicReplicantEntityIterator ~~~~~~~~~~~~~~~
HostManager__DynamicReplicantEntityIterator::
HostManager__DynamicReplicantEntityIterator(
HostManager *host_manager
):
Host__DynamicReplicantEntityIterator(host_manager->localHost)
{
}
HostManager__DynamicReplicantEntityIterator::
~HostManager__DynamicReplicantEntityIterator()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~ HostManager__RemoteHostIterator ~~~~~~~~~~~~~~~~~~~~
HostManager__RemoteHostIterator::HostManager__RemoteHostIterator(
HostManager *host_manager
):
TableIteratorOf<Host*, HostID>(&host_manager->remoteHostSocket)
{
}
HostManager__RemoteHostIterator::~HostManager__RemoteHostIterator()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~ HostManager__AllHostIterator ~~~~~~~~~~~~~~~~~~~~~~~
HostManager__AllHostIterator::HostManager__AllHostIterator(
HostManager *host_manager
):
TableIteratorOf<Host*, HostID>(&host_manager->allHostSocket)
{
}
HostManager__AllHostIterator::~HostManager__AllHostIterator()
{
}
#if 0
# if defined(TEST_CLASS)
# include "host.tcp"
# endif
#endif