Files
source/Laptop/PostalService.h
T
b5ea70aa44 declare the postal service iterators as values, not as references
PostalService.h names every type twice, once plainly and once as a reference:
RefToDestinationStruct is DestinationStruct&, RefToShipmentList is
ShipmentList&. That scheme was extended to the iterators, and there it does
not work. Every one of the seventeen uses looks like this:

    RefToShipmentListIterator sli = _Shipments.begin();

begin() returns a value, so this binds a non-const reference to a temporary.
MSVC allows it as an extension; the temporary still dies at the end of the
full expression, which leaves sli referring to a dead object for the whole
rest of the function. It works only because nothing has reused the stack slot
yet. clang rejects it outright.

Iterators are already handles into their container, so a reference to one buys
nothing: the plain typedef says exactly what these seventeen variables want to
be. DESTINATION and SHIPMENT now take theirs by value, which changes nothing
for either, as both only dereference the iterator they are given.

Two of the reference typedefs, RefToDestinationDeliveryInfoTableIterator and
RefToDeliveryCallbackDataListIterator, had no uses at all. They are removed
rather than left behind, since their only possible use is the pattern this
commit removes.

Verification:

    grep -rn 'RefTo[A-Za-z]*Iterator' --include=*.cpp --include=*.h .   # nothing
    ninja -C build parse         # bind-to-temporary class gone: 91 -> 60 sites
    ninja -C build -k 0          # Release, four applications, green
    ninja -C build-debug -k 0    # Debug, four applications, green

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 19:29:55 -03:00

255 lines
8.4 KiB
C++

#ifndef __POSTAL_SERVICE_H
#define __POSTAL_SERVICE_H
#include "SaveLoadMap.h"
#include "Structure Wrap.h"
#include "Tactical Save.h"
#include "LaptopSave.h"
#include "PostalService.h"
#include "Isometric Utils.h"
#include "DEBUG.H"
#include "Game Event Hook.h"
#include "Game Events.h"
#include <list>
#include <string>
#include <iostream>
using namespace std;
#define MAX_DEST_NAME_LENGTH 32
#define MAX_DELIVERYMETHOD_DESC_LENGTH 32
#define MAX_DESTINATIONS 255
#define MAX_SHIPMENTS 255
//////////////////////////////////////////////
class CPostalService;
typedef CPostalService& RefToCPostalService;
typedef CPostalService* PCPostalService;
//////////////////////////////////////////////
typedef struct
{
UINT16 usID;
UINT32 uiIndex; // uiIndex is used as an ID number in external game data
UINT8 ubMapY;
UINT8 ubMapX;
UINT8 ubMapZ;
UINT32 sGridNo;
wstring wstrName;
} DestinationStruct;
typedef DestinationStruct& RefToDestinationStruct;
typedef DestinationStruct* PDestinationStruct;
typedef list<DestinationStruct> DestinationList;
typedef list<DestinationStruct>& RefToDestinationList;
typedef DestinationList::const_iterator DestinationListIterator;
inline RefToDestinationStruct DESTINATION(DestinationListIterator dli)
{
return ( (RefToDestinationStruct) *dli );
}
inline BOOLEAN DESTINATION_ID_GREATER(RefToDestinationStruct d1, RefToDestinationStruct d2)
{
return (d1.usID > d2.usID);
}
#define DESTINATION_LIST_DESCENDING DESTINATION_ID_GREATER
inline BOOLEAN DESTINATION_ID_LOWER(RefToDestinationStruct d1, RefToDestinationStruct d2)
{
return (d1.usID < d2.usID);
}
#define DESTINATION_LIST_ASCENDING DESTINATION_ID_LOWER
inline BOOLEAN DESTINATION_ID_EQUAL(RefToDestinationStruct d1, RefToDestinationStruct d2)
{
return (d1.usID == d2.usID);
}
//////////////////////////////////////////////////////////////
typedef struct
{
UINT8 ubParentDeliveryMethodIndex;
UINT16 usDestinationFee;
INT8 bDaysAhead;
}DestinationDeliveryInfoStruct;
typedef DestinationDeliveryInfoStruct& RefToDestinationDeliveryInfoStruct;
typedef DestinationDeliveryInfoStruct* PDestinationDeliveryInfoStruct;
typedef vector<DestinationDeliveryInfoStruct> DestinationDeliveryInfoTable;
typedef DestinationDeliveryInfoTable* PDestinationDeliveryInfoTable;
typedef DestinationDeliveryInfoTable& RefToDestinationDeliveryInfoTable;
typedef DestinationDeliveryInfoTable::iterator DestinationDeliveryInfoTableIterator;
typedef struct
{
wstring wstrDescription;
PDestinationDeliveryInfoTable pDestinationDeliveryInfos;
} DeliveryMethodStruct;
typedef DeliveryMethodStruct& RefToDeliveryMethodStruct;
typedef DeliveryMethodStruct* PDeliveryMethodStruct;
typedef vector<DeliveryMethodStruct> DeliveryMethodTable;
typedef DeliveryMethodTable& RefToDeliveryMethodTable;
/////////////////////////////////////////////////////////////
typedef struct
{
UINT16 usItemIndex;
UINT8 ubNumber;
INT8 bItemQuality;
} ShipmentPackageStruct;
typedef ShipmentPackageStruct& RefToShipmentPackageStruct;
typedef ShipmentPackageStruct* PShipmentPackageStruct;
typedef vector<ShipmentPackageStruct> ShipmentPackageList;
typedef ShipmentPackageList& RefToShipmentPackageList;
typedef ShipmentPackageList::iterator ShipmentPackageListIterator;
typedef enum
{
SHIPMENT_STATIONARY=0,
SHIPMENT_INTRANSIT,
SHIPMENT_CANCEL_DELIVERY
} SHIPMENT_STATUS;
typedef struct
{
UINT16 usID;
SHIPMENT_STATUS ShipmentStatus;
ShipmentPackageList ShipmentPackages;
PDestinationStruct pDestination;
PDestinationDeliveryInfoStruct pDestinationDeliveryInfo;
INT16 sSenderID; // For now, two senders exist: Bobby Ray(0) and John Kulba(1)
INT16 sReceiverID; // Unused for now, but reserved for future projects
UINT32 uiOrderDate;
} ShipmentStruct;
typedef ShipmentStruct& RefToShipmentStruct;
typedef ShipmentStruct* PShipmentStruct;
typedef list<ShipmentStruct> ShipmentList;
typedef ShipmentList* PShipmentList;
typedef ShipmentList& RefToShipmentList;
typedef ShipmentList::iterator ShipmentListIterator;
typedef struct
{
UINT32 uiNumberOfShipments;
UINT32 uiShipmentDataSize;
UINT32 uiPackageDataSize;
}ShipmentListSaveFileDataHeaderStruct;
typedef ShipmentListSaveFileDataHeaderStruct* PShipmentListSaveFileDataHeaderStruct;
typedef struct
{
UINT16 usID;
SHIPMENT_STATUS ShipmentStatus;
UINT32 uiNumberOfPackages;
UINT16 usDestinationID;
UINT8 ubDeliveryMethodIndex;
INT16 sSenderID;
INT16 sReceiverID;
UINT32 uiOrderDate;
} ShipmentSaveFileDataStruct;
typedef ShipmentSaveFileDataStruct* PShipmentSaveFileDataStruct;
inline BOOLEAN SHIPMENT_ID_LOWER(RefToShipmentStruct s1, RefToShipmentStruct s2)
{
return (s1.usID < s2.usID);
}
#define SHIPMENT_LIST_ASCENDING SHIPMENT_ID_LOWER
inline RefToShipmentStruct SHIPMENT(ShipmentListIterator sli)
{
return ( (RefToShipmentStruct) *sli );
}
////////////////////////////////////////////////////////////////
class CShipmentManipulator
{
friend CPostalService;
public:
INT16 GetSenderID(void);
RefToDestinationStruct GetDestination(void) const;
void ContinueCallbackChain(BOOLEAN fContinue);
void CancelDelivery(void);
CShipmentManipulator(PCPostalService Owner, PShipmentStruct Shipment);
private:
PCPostalService _PostalService;
PShipmentStruct _Shipment;
BOOLEAN _fContinueCallbackChain;
};
typedef CShipmentManipulator& RefToCShipmentManipulator;
typedef CShipmentManipulator* PCShipmentManipulator;
typedef void (*PtrToDeliveryCallbackFunc)(RefToCShipmentManipulator ShipmentManipulator);
typedef struct
{
INT16 sSenderID;
PtrToDeliveryCallbackFunc DeliveryCallbackFunc;
} DeliveryCallbackDataStruct;
typedef DeliveryCallbackDataStruct& RefToDeliveryCallbackDataStruct;
typedef vector<DeliveryCallbackDataStruct> DeliveryCallbackDataList;
typedef DeliveryCallbackDataList& RefToDeliveryCallbackDataList;
typedef DeliveryCallbackDataList::iterator DeliveryCallbackDataListIterator;
////////////////////////////////////////////////////////////////
class CPostalService
{
friend BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent );
friend CShipmentManipulator;
public:
// Shipment management
UINT16 CreateNewShipment(UINT16 usDestinationID, UINT8 ubDeliveryMethodIndex, INT16 sSenderID);
BOOLEAN AddPackageToShipment(UINT16 usShipmentID, UINT16 usItemIndex, UINT8 ubNumber, INT8 bItemQuality);
BOOLEAN SendShipment(UINT16 usShipmentID);
BOOLEAN DeliverShipment(UINT16 usShipmentID);
BOOLEAN DeliverShipmentForMultiplayer(UINT16 usShipmentID);
BOOLEAN RegisterDeliveryCallback(INT16 sSenderID, PtrToDeliveryCallbackFunc DeliveryCallbackFunc);
// Interfaces
BOOLEAN LoadShipmentListFromSaveGameFile(HWFILE hFile);
BOOLEAN SaveShipmentListToSaveGameFile(HWFILE hFile);
// Shipment utility functions
UINT16 GetShipmentCount(SHIPMENT_STATUS TargetedShipmentStatus);
RefToShipmentList LookupShipmentList(void) const;
// Destination management
UINT16 AddDestination(UINT32 uiIndex, UINT8 ubMapX, UINT8 ubMapY, UINT8 ubMapZ, UINT32 sGridNo, STR16 pszName );
UINT16 RemoveDestination(UINT16 usDestinationID);
RefToDestinationStruct GetDestination(UINT16 usDestinationID) const;
RefToDestinationList LookupDestinationList(void) const;
// WANNE:
BOOLEAN IsSectorAShipmentSector(UINT8 ubMapX, UINT8 ubMapY, UINT8 ubMapZ);
// Delivery method management
UINT8 AddDeliveryMethod(STR16 pszDescription);
UINT16 SetDestinationDeliveryInfo(UINT8 ubDeliveryMethodIndex, UINT32 uiDestinationIndex, UINT16 usDestinationFee, INT8 bDaysAhead);
UINT16 GetDestinationFee(UINT8 ubDeliveryMethodIndex, UINT16 usDestinationID);
RefToDeliveryMethodStruct GetDeliveryMethod(UINT8 ubDeliveryMethodIndex) const;
void Clear(bool clearOnlyData);
CPostalService();
private:
ShipmentList _Shipments;
vector<BOOLEAN> _UsedShipmentIDList;
DeliveryCallbackDataList _DeliveryCallbacks;
static OBJECTTYPE tempObject;
// All instances share the same set of destinations...
static DestinationList _Destinations;
static vector<BOOLEAN> _UsedDestinationIDList;
RefToDestinationStruct _GetDestination(UINT16 usDestinationID);
// ...but they may have different delivery methods available so these are managed individually
DeliveryMethodTable _DeliveryMethods;
RefToDestinationDeliveryInfoStruct _GetDestinationDeliveryInfo(UINT8 ubDeliveryMethodIndex, UINT16 usDestinationID);
protected:
};
#endif