BT410 5.3.105: L4SPLR restored -- the mission-review spool layer, back-dated from the surviving RP411 descendant
No 1995 L4SPLR.CPP survives, but its header does, and the direct descendant
source survives in the RP411 tree. This is that 741-line file back-dated
onto the 1995 engine APIs the header declares -- the BACKFILLS method -- and
the ENGINE COUNT MOVES: 181 -> 182 TUs, link clean, zero unresolved.
What the brick is: the whole mission-review spool layer --
SpoolingInterestManager every interest packet -> the spool
L4SpoolingNetworkManager normal connect + the spool PREAMBLE (app ID,
data version, per-host remote/local + HostID)
L4PlaybackNetworkManager "connect" FROM the spool: verify the preamble,
rebuild the host table with no wire, post Load
L4SpoolingApplication the recorder app -- renderless makers, deferred
stop (spool the ending exactly once), hand the
finished spool to the application manager
SpoolerTask the playback pump: egg packets while waiting,
interest packets while loading, then everything
doled out on recorded timestamps + GetTimeBias()
Back-dating deltas, each named in the header block: the HINSTANCE/HWND ctor
reverts to (ResourceFile*, ApplicationID); SOCKADDR_IN + two-arg
ResolveAddress revert to the 1995 unsigned-long address; L4Host construction
uses NullNetworkAddress/0 (L4NET.CPP's own idiom); PostQuitMessage becomes
Exit_Code = AbortExitCodeID (the loop gate ExecuteForeground already tests);
accessor-style statics revert to the header's static members; and the
later-era MakeGaugeRenderer/Shutdown parameters drop.
Two BC4.52 notes in source: the StopMissionMessage re-post carries an
explicit (Receiver::Message *) cast for the compiler's nested-scope upcast
quirk (NetworkClient derives Receiver, so the type IS right), and the
foreground tick casts to LBE4ControlsManager::Execute exactly as L4APP does
(the 1995 base ControlsManager has no Execute).
KNOWN DEBT, deliberately left: L4PlaybackNetworkManager::DefaultData is
referenced by its ctor but defined nowhere yet -- the linker does not pull
the member because nothing references the playback manager until BTL4PB.CPP
exists. That definition belongs with the playback app increment, which is
next. Regression run clean (same y-track terrain walk).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,741 @@
|
||||
//===========================================================================//
|
||||
// File: l4splr.cpp //
|
||||
// Project: MUNGA Brick: L4 Spooling / Playback //
|
||||
// Contents: The mission-review spool layer -- the recorder-side network //
|
||||
// managers, the spooling application, and the playback pump //
|
||||
//---------------------------------------------------------------------------//
|
||||
// Date Who Modification //
|
||||
// -------- --- ---------------------------------------------------------- //
|
||||
// //
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
|
||||
// All Rights reserved worldwide //
|
||||
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
||||
//===========================================================================//
|
||||
//
|
||||
// RECONSTRUCTION: no 1995 L4SPLR.CPP survives, but its HEADER does
|
||||
// (CODE/RP/MUNGA_L4/L4SPLR.HPP), and the direct descendant source survives
|
||||
// in the RP411 tree (MUNGA_L4/L4SPLR.cpp) -- this file is that source
|
||||
// BACK-DATED onto the 1995 engine APIs the header declares, the same method
|
||||
// as the MUNGA backfills (BACKFILLS.NOTES.md). Deltas from the RP411 body:
|
||||
//
|
||||
// * the windowing-era ctor (HINSTANCE/HWND) reverts to the header's
|
||||
// (ResourceFile *, ApplicationID);
|
||||
// * SOCKADDR_IN + two-arg ResolveAddress revert to the 1995
|
||||
// unsigned-long address (L4NET.HPP:265) and FindHost(NetworkAddress);
|
||||
// * L4Host construction takes NullNetworkAddress / socket 0, the same
|
||||
// idiom as L4NET.CPP's own console-host build;
|
||||
// * PostQuitMessage(AbortExitCodeID) becomes Exit_Code = AbortExitCodeID
|
||||
// (the 1995 loop gate ExecuteForeground already tests);
|
||||
// * accessor-style statics revert to the header's static members;
|
||||
// * MakeGaugeRenderer()/Shutdown() lose their later-era parameters.
|
||||
//
|
||||
|
||||
#include <mungal4.hpp>
|
||||
#pragma hdrstop
|
||||
|
||||
#if !defined(L4SPLR_HPP)
|
||||
# include <l4splr.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(L4NET_HPP)
|
||||
# include <l4net.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(MISSION_HPP)
|
||||
# include <mission.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(APP_HPP)
|
||||
# include <app.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(L4CTRL_HPP)
|
||||
# include <l4ctrl.hpp>
|
||||
#endif
|
||||
|
||||
//#############################################################################
|
||||
//###################### SpoolingInterestManager ##########################
|
||||
//#############################################################################
|
||||
|
||||
SpoolingInterestManager::SpoolingInterestManager()
|
||||
{
|
||||
}
|
||||
|
||||
SpoolingInterestManager::~SpoolingInterestManager()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
SpoolingInterestManager::LoadInterestArenas(Mission *)
|
||||
{
|
||||
Check(this);
|
||||
}
|
||||
|
||||
void
|
||||
SpoolingInterestManager::LoadMission(Mission *)
|
||||
{
|
||||
Check(this);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// Every network message reaching the interest manager is spooled.
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
SpoolingInterestManager::ReceiveNetworkPacket(
|
||||
NetworkPacket *packet,
|
||||
Receiver::Message *
|
||||
)
|
||||
{
|
||||
packet->timeStamp = Now();
|
||||
|
||||
Check(l4_spooling_application);
|
||||
SpoolFile
|
||||
*spool = l4_spooling_application->GetSpoolFile();
|
||||
Check(spool);
|
||||
spool->SpoolPacket(packet);
|
||||
}
|
||||
|
||||
void
|
||||
SpoolingInterestManager::Shutdown()
|
||||
{
|
||||
Check(this);
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
//###################### L4SpoolingNetworkManager #########################
|
||||
//#############################################################################
|
||||
|
||||
L4SpoolingNetworkManager::L4SpoolingNetworkManager()
|
||||
{
|
||||
}
|
||||
|
||||
L4SpoolingNetworkManager::~L4SpoolingNetworkManager()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// Start the connection normally, then write the spool PREAMBLE: the
|
||||
// application ID, the resource major version, and per mission host a
|
||||
// remote/local flag plus its host ID -- everything playback needs to
|
||||
// reconstruct the host table without a live network.
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
L4SpoolingNetworkManager::StartConnecting(Mission *mission)
|
||||
{
|
||||
L4NetworkManager::StartConnecting(mission);
|
||||
|
||||
Check(l4_spooling_application);
|
||||
SpoolFile
|
||||
*spool = l4_spooling_application->GetSpoolFile();
|
||||
Check(spool);
|
||||
|
||||
*(ApplicationID *)spool->GetPointer() = application->GetApplicationID();
|
||||
spool->AdvancePointer(sizeof(ApplicationID));
|
||||
|
||||
ResourceFile
|
||||
*res_file = application->GetResourceFile();
|
||||
Check(res_file);
|
||||
int
|
||||
major_version = res_file->versionArray[1];
|
||||
*(int *)spool->GetPointer() = major_version;
|
||||
spool->AdvancePointer(sizeof(major_version));
|
||||
|
||||
HostManager
|
||||
*host_mgr = application->GetHostManager();
|
||||
Check(host_mgr);
|
||||
|
||||
Mission::HostIterator
|
||||
mission_host_iterator(mission);
|
||||
MissionHostData
|
||||
*mission_host_data;
|
||||
|
||||
while ((mission_host_data = mission_host_iterator.ReadAndNext()) != NULL)
|
||||
{
|
||||
CString
|
||||
host_name(mission_host_data->GetAddressString());
|
||||
unsigned long
|
||||
net_address = ResolveAddress(host_name);
|
||||
Host
|
||||
*host = host_mgr->FindHost(net_address);
|
||||
|
||||
*(Logical *)spool->GetPointer() = (host != host_mgr->GetLocalHost());
|
||||
spool->AdvancePointer(sizeof(Logical));
|
||||
|
||||
*(HostID *)spool->GetPointer() = host->GetHostID();
|
||||
spool->AdvancePointer(sizeof(HostID));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// Egg traffic is spooled on its way through.
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
L4SpoolingNetworkManager::ReceiveNetworkPacket(
|
||||
NetworkPacket *packet,
|
||||
Receiver::Message *message
|
||||
)
|
||||
{
|
||||
if (message->messageID == ReceiveEggFileMessageID)
|
||||
{
|
||||
packet->timeStamp = Now();
|
||||
Check(l4_spooling_application);
|
||||
SpoolFile
|
||||
*spool = l4_spooling_application->GetSpoolFile();
|
||||
Check(spool);
|
||||
spool->SpoolPacket(packet);
|
||||
}
|
||||
L4NetworkManager::ReceiveNetworkPacket(packet, message);
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
//###################### L4PlaybackNetworkManager #########################
|
||||
//#############################################################################
|
||||
|
||||
L4PlaybackNetworkManager::L4PlaybackNetworkManager():
|
||||
NetworkManager(L4PlaybackNetworkManager::DefaultData)
|
||||
{
|
||||
}
|
||||
|
||||
L4PlaybackNetworkManager::~L4PlaybackNetworkManager()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// "Connect" from the spool instead of the wire: read back the preamble the
|
||||
// spooler wrote, verify it belongs to this application and data version,
|
||||
// rebuild the host table from the recorded flags, and post LoadMission.
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
L4PlaybackNetworkManager::StartConnecting(Mission *mission)
|
||||
{
|
||||
Mission::HostIterator
|
||||
mission_host_iterator(mission);
|
||||
MissionHostData
|
||||
*mission_host_data;
|
||||
|
||||
Check(application);
|
||||
SpoolFile
|
||||
*spool = application->GetSpoolFile();
|
||||
Check(spool);
|
||||
|
||||
ApplicationID
|
||||
id = *(ApplicationID *)spool->GetPointer();
|
||||
spool->AdvancePointer(sizeof(id));
|
||||
int
|
||||
major_rev = *(int *)spool->GetPointer();
|
||||
spool->AdvancePointer(sizeof(major_rev));
|
||||
|
||||
if (id != application->GetApplicationID())
|
||||
{
|
||||
DEBUG_STREAM
|
||||
<< "\n\nError - Not a spool file for this application!\n" << flush;
|
||||
Exit_Code = AbortExitCodeID;
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceFile
|
||||
*resource_file = application->GetResourceFile();
|
||||
Check(resource_file);
|
||||
|
||||
if (major_rev != resource_file->versionArray[1])
|
||||
{
|
||||
DEBUG_STREAM
|
||||
<< "\n\nError - Spool file major data version should be "
|
||||
<< (int)resource_file->versionArray[1] << ", not " << major_rev
|
||||
<< "!\n" << flush;
|
||||
Exit_Code = AbortExitCodeID;
|
||||
return;
|
||||
}
|
||||
|
||||
HostManager
|
||||
*host_mgr = application->GetHostManager();
|
||||
Check(host_mgr);
|
||||
|
||||
while ((mission_host_data = mission_host_iterator.ReadAndNext()) != NULL)
|
||||
{
|
||||
Check(mission_host_data);
|
||||
CString
|
||||
host_name(mission_host_data->GetAddressString());
|
||||
|
||||
Logical
|
||||
remote = *(Logical *)spool->GetPointer();
|
||||
spool->AdvancePointer(sizeof(Logical));
|
||||
HostID
|
||||
host_id = *(HostID *)spool->GetPointer();
|
||||
spool->AdvancePointer(sizeof(HostID));
|
||||
|
||||
Host
|
||||
*my_host =
|
||||
new L4Host(
|
||||
host_id,
|
||||
mission_host_data->GetHostType(),
|
||||
NullNetworkAddress,
|
||||
0,
|
||||
host_name
|
||||
);
|
||||
Register_Object(my_host);
|
||||
if (remote)
|
||||
{
|
||||
host_mgr->AdoptRemoteHost(my_host);
|
||||
}
|
||||
else
|
||||
{
|
||||
host_mgr->AdoptLocalHost(my_host);
|
||||
}
|
||||
}
|
||||
|
||||
Check(application);
|
||||
Application::Message
|
||||
load_message(
|
||||
Application::LoadMissionMessageID,
|
||||
sizeof(Application::Message)
|
||||
);
|
||||
application->Post(DefaultEventPriority, application, &load_message);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
Logical
|
||||
L4PlaybackNetworkManager::Shutdown()
|
||||
{
|
||||
Check(this);
|
||||
NetworkManager::Shutdown();
|
||||
|
||||
Check(application);
|
||||
HostManager
|
||||
*host_mgr = application->GetHostManager();
|
||||
Check(host_mgr);
|
||||
HostManager::RemoteHostIterator
|
||||
remote_hosts(host_mgr);
|
||||
Host
|
||||
*my_host;
|
||||
while ((my_host = remote_hosts.ReadAndNext()) != NULL)
|
||||
{
|
||||
Check(my_host);
|
||||
host_mgr->OrphanRemoteHost(my_host);
|
||||
Unregister_Object(my_host);
|
||||
delete my_host;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
//
|
||||
// Playback has no live wire: the buffers are always empty.
|
||||
//
|
||||
Logical
|
||||
L4PlaybackNetworkManager::CheckBuffers(NetworkPacket *)
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
//###################### L4SpoolingApplication ##########################
|
||||
//#############################################################################
|
||||
|
||||
L4SpoolingApplication
|
||||
*&l4_spooling_application = (L4SpoolingApplication *&)application;
|
||||
|
||||
const Receiver::HandlerEntry
|
||||
L4SpoolingApplication::MessageHandlerEntries[] =
|
||||
{
|
||||
MESSAGE_ENTRY(L4SpoolingApplication, RunMission),
|
||||
MESSAGE_ENTRY(L4SpoolingApplication, StopMission),
|
||||
MESSAGE_ENTRY(L4SpoolingApplication, AbortMission),
|
||||
MESSAGE_ENTRY(L4SpoolingApplication, LoadMission)
|
||||
};
|
||||
|
||||
L4SpoolingApplication::MessageHandlerSet
|
||||
L4SpoolingApplication::MessageHandlers(
|
||||
ELEMENTS(L4SpoolingApplication::MessageHandlerEntries),
|
||||
L4SpoolingApplication::MessageHandlerEntries,
|
||||
L4Application::MessageHandlers
|
||||
);
|
||||
|
||||
Derivation
|
||||
L4SpoolingApplication::ClassDerivations(
|
||||
L4Application::ClassDerivations,
|
||||
"L4SpoolingApplication"
|
||||
);
|
||||
|
||||
L4SpoolingApplication::SharedData
|
||||
L4SpoolingApplication::DefaultData(
|
||||
L4SpoolingApplication::ClassDerivations,
|
||||
L4SpoolingApplication::MessageHandlers
|
||||
);
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
L4SpoolingApplication::L4SpoolingApplication(
|
||||
ResourceFile *resource_file,
|
||||
ApplicationID application_ID
|
||||
):
|
||||
L4Application(
|
||||
resource_file,
|
||||
application_ID,
|
||||
L4ApplicationClassID,
|
||||
DefaultData
|
||||
)
|
||||
{
|
||||
missionSpooled = False;
|
||||
}
|
||||
|
||||
L4SpoolingApplication::~L4SpoolingApplication()
|
||||
{
|
||||
}
|
||||
|
||||
Logical
|
||||
L4SpoolingApplication::TestInstance() const
|
||||
{
|
||||
return IsDerivedFrom(ClassDerivations);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// Message handlers.
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
L4SpoolingApplication::LoadMissionMessageHandler(Message *)
|
||||
{
|
||||
applicationState.SetState(WaitingForLaunch);
|
||||
}
|
||||
|
||||
void
|
||||
L4SpoolingApplication::RunMissionMessageHandler(RunMissionMessage *)
|
||||
{
|
||||
Check(this);
|
||||
applicationState.SetState(RunningMission);
|
||||
}
|
||||
|
||||
//
|
||||
// The stop is deferred until the mission has fully spooled, then the spool
|
||||
// is handed to the application manager for storage.
|
||||
//
|
||||
void
|
||||
L4SpoolingApplication::StopMissionMessageHandler(StopMissionMessage *message)
|
||||
{
|
||||
if (!missionSpooled)
|
||||
{
|
||||
missionSpooled = True;
|
||||
|
||||
Time
|
||||
post_time = Now();
|
||||
post_time += 3.0f;
|
||||
|
||||
//
|
||||
// The StopMissionMessage IS a Receiver::Message (NetworkClient
|
||||
// derives Receiver, so NetworkClient::Message resolves there); the
|
||||
// explicit cast is for BC4.52's nested-scope upcast quirk only.
|
||||
//
|
||||
Post(
|
||||
DefaultEventPriority, this,
|
||||
(Receiver::Message *)message, post_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
MissionReviewApplicationManager
|
||||
*app_mgr = GetApplicationManager();
|
||||
Check(app_mgr);
|
||||
SpoolFile
|
||||
*spool = GetSpoolFile();
|
||||
Check(spool);
|
||||
app_mgr->StoreSpoolFile(spool);
|
||||
spoolFile = NULL;
|
||||
|
||||
L4Application::StopMissionMessageHandler(message);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
L4SpoolingApplication::AbortMissionMessageHandler(
|
||||
AbortMissionMessage *message
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
Check(spoolFile);
|
||||
spoolFile->Rewind();
|
||||
|
||||
L4Application::AbortMissionMessageHandler(message);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// Run/stop traffic is spooled on its way through -- the stop only once the
|
||||
// mission has been marked spooled, so the recorded file ends exactly once.
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
L4SpoolingApplication::ReceiveNetworkPacket(
|
||||
NetworkPacket *packet,
|
||||
Receiver::Message *message
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
|
||||
SpoolFile
|
||||
*spool;
|
||||
switch (message->messageID)
|
||||
{
|
||||
case StopMissionMessageID:
|
||||
if (missionSpooled)
|
||||
{
|
||||
packet->timeStamp = Now();
|
||||
spool = GetSpoolFile();
|
||||
Check(spool);
|
||||
spool->SpoolPacket(packet);
|
||||
break;
|
||||
}
|
||||
// fall through -- an un-spooled stop records like a run
|
||||
|
||||
case RunMissionMessageID:
|
||||
packet->timeStamp = Now();
|
||||
spool = GetSpoolFile();
|
||||
Check(spool);
|
||||
spool->SpoolPacket(packet);
|
||||
break;
|
||||
}
|
||||
L4Application::ReceiveNetworkPacket(packet, message);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// The maker overrides: a spooler records; it does not render.
|
||||
//#############################################################################
|
||||
//
|
||||
Registry *
|
||||
L4SpoolingApplication::MakeRegistry()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
InterestManager *
|
||||
L4SpoolingApplication::MakeInterestManager()
|
||||
{
|
||||
return new SpoolingInterestManager;
|
||||
}
|
||||
|
||||
NetworkManager *
|
||||
L4SpoolingApplication::MakeNetworkManager()
|
||||
{
|
||||
return new L4SpoolingNetworkManager;
|
||||
}
|
||||
|
||||
VideoRenderer *
|
||||
L4SpoolingApplication::MakeVideoRenderer()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AudioRenderer *
|
||||
L4SpoolingApplication::MakeAudioRenderer()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GaugeRenderer *
|
||||
L4SpoolingApplication::MakeGaugeRenderer()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Mission *
|
||||
L4SpoolingApplication::MakeMission(
|
||||
NotationFile *notation_file,
|
||||
ResourceFile *resources
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
Check(notation_file);
|
||||
Check(resources);
|
||||
|
||||
return new Mission(notation_file, resources);
|
||||
}
|
||||
|
||||
Entity *
|
||||
L4SpoolingApplication::MakeViewpointEntity(Entity__MakeMessage *)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
L4SpoolingApplication::Initialize()
|
||||
{
|
||||
Check(this);
|
||||
Application::Initialize();
|
||||
|
||||
L4NetworkManager
|
||||
*net_mgr = GetNetworkManager();
|
||||
Check(net_mgr);
|
||||
net_mgr->CreateConsoleHost();
|
||||
|
||||
MissionReviewApplicationManager
|
||||
*app_mgr = GetApplicationManager();
|
||||
Check(app_mgr);
|
||||
spoolFile = app_mgr->GetEmptySpoolFile();
|
||||
}
|
||||
|
||||
void
|
||||
L4SpoolingApplication::LoadBackgroundTasks()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
Logical
|
||||
L4SpoolingApplication::ExecuteForeground(
|
||||
Time /* start_of_frame */,
|
||||
Scalar /* frame_duration */
|
||||
)
|
||||
{
|
||||
SET_FOREGROUND_PROCESSING();
|
||||
Check(this);
|
||||
|
||||
//
|
||||
// The 1995 base ControlsManager has no Execute; the LBE4 subclass owns
|
||||
// the per-frame poll (L4CTRL.HPP:225), same cast L4APP itself uses.
|
||||
//
|
||||
Check(controlsManager);
|
||||
((LBE4ControlsManager *)controlsManager)->Execute();
|
||||
|
||||
CLEAR_FOREGROUND_PROCESSING();
|
||||
return executeFrames && !Exit_Code;
|
||||
}
|
||||
|
||||
void
|
||||
L4SpoolingApplication::ExecuteBackgroundTask()
|
||||
{
|
||||
Check(this);
|
||||
|
||||
Check(networkManager);
|
||||
if (!networkManager->RoutePacket())
|
||||
{
|
||||
ProcessOneEvent(DefaultEventPriority);
|
||||
}
|
||||
}
|
||||
|
||||
Logical
|
||||
L4SpoolingApplication::Shutdown()
|
||||
{
|
||||
Check(this);
|
||||
|
||||
L4Application::Shutdown();
|
||||
return !Exit_Code && !missionSpooled;
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
//########################### SpoolerTask ###############################
|
||||
//#############################################################################
|
||||
|
||||
SpoolerTask::SpoolerTask()
|
||||
{
|
||||
}
|
||||
|
||||
SpoolerTask::~SpoolerTask()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SpoolerTask::DispatchPacket(NetworkPacket *)
|
||||
{
|
||||
Fail("SpoolerTask::DispatchPacket - shouldn't be here!");
|
||||
}
|
||||
|
||||
long
|
||||
SpoolerTask::GetTimeBias()
|
||||
{
|
||||
Fail("SpoolerTask::GetTimeBias - shouldn't be here!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// The playback pump: interpret the spool against the application state --
|
||||
// egg packets while waiting for the egg, interest packets while loading,
|
||||
// then everything else doled out on the recorded timestamps biased by when
|
||||
// the run began.
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
SpoolerTask::Execute()
|
||||
{
|
||||
Check(this);
|
||||
Check(application);
|
||||
|
||||
SpoolFile
|
||||
*spool = application->GetSpoolFile();
|
||||
if (!spool)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Check(spool);
|
||||
NetworkPacket
|
||||
*packet;
|
||||
switch (application->GetApplicationState())
|
||||
{
|
||||
case Application::WaitingForEgg:
|
||||
packet = (NetworkPacket *)spool->GetPointer();
|
||||
while (packet->clientID == NetworkClient::NetworkManagerClientID)
|
||||
{
|
||||
spool->NextPacket();
|
||||
DispatchPacket(packet);
|
||||
packet = (NetworkPacket *)spool->GetPointer();
|
||||
}
|
||||
break;
|
||||
|
||||
case Application::CreatingMission:
|
||||
case Application::LoadingMission:
|
||||
packet = (NetworkPacket *)spool->GetPointer();
|
||||
while (
|
||||
packet->clientID != NetworkClient::ApplicationClientID &&
|
||||
spool->GetBytesRemaining() > 0
|
||||
)
|
||||
{
|
||||
spool->NextPacket();
|
||||
DispatchPacket(packet);
|
||||
packet = (NetworkPacket *)spool->GetPointer();
|
||||
}
|
||||
break;
|
||||
|
||||
case Application::LaunchingMission:
|
||||
case Application::RunningMission:
|
||||
while (spool && spool->GetBytesRemaining() > 0)
|
||||
{
|
||||
packet = (NetworkPacket *)spool->GetPointer();
|
||||
Time
|
||||
when = packet->timeStamp;
|
||||
when.ticks += GetTimeBias();
|
||||
if (when > Now())
|
||||
{
|
||||
break;
|
||||
}
|
||||
spool->NextPacket();
|
||||
DispatchPacket(packet);
|
||||
spool = application->GetSpoolFile();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user