44 changes: 43 additions & 1 deletion src/structure.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ extern void factoryLoopAdjust(STRUCTURE *psStruct, bool add);

/*cancels the production run for the factory and returns any power that was
accrued but not used*/
extern void cancelProduction(STRUCTURE *psBuilding, QUEUE_MODE mode);
void cancelProduction(STRUCTURE *psBuilding, QUEUE_MODE mode, bool mayClearProductionRun = true);

/*set a factory's production run to hold*/
extern void holdProduction(STRUCTURE *psBuilding, QUEUE_MODE mode);
Expand Down Expand Up @@ -455,6 +455,48 @@ static inline void _setStructureTarget(STRUCTURE *psBuilding, BASE_OBJECT *psNew
#endif
}

// Functions for the GUI to know what's pending, before it's synchronised.
template<typename Functionality, typename Subject>
static inline void setStatusPendingStart(Functionality &functionality, Subject *subject)
{
functionality.psSubjectPending = subject;
functionality.statusPending = FACTORY_START_PENDING;
++functionality.pendingCount;
}

template<typename Functionality>
static inline void setStatusPendingCancel(Functionality &functionality)
{
functionality.psSubjectPending = NULL;
functionality.statusPending = FACTORY_CANCEL_PENDING;
++functionality.pendingCount;
}

template<typename Functionality>
static inline void setStatusPendingHold(Functionality &functionality)
{
if (functionality.psSubjectPending == NULL)
{
functionality.psSubjectPending = functionality.psSubject;
}
functionality.statusPending = FACTORY_HOLD_PENDING;
++functionality.pendingCount;
}

template<typename Functionality>
static inline void setStatusPendingRelease(Functionality &functionality)
{
if (functionality.psSubjectPending == NULL && functionality.statusPending != FACTORY_CANCEL_PENDING)
{
functionality.psSubjectPending = functionality.psSubject;
}
if (functionality.psSubjectPending != NULL)
{
functionality.statusPending = FACTORY_START_PENDING;
}
++functionality.pendingCount;
}

void checkStructure(const STRUCTURE* psStructure, const char * const location_description, const char * function, const int recurse);

#define CHECK_STRUCTURE(object) checkStructure((object), AT_MACRO, __FUNCTION__, max_check_object_recursion)
Expand Down
20 changes: 11 additions & 9 deletions src/structuredef.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,27 +150,29 @@ enum STRUCT_STATES
SS_BLUEPRINT_PLANNED_BY_ALLY,
};

enum StatusPending
{
FACTORY_NOTHING_PENDING = 0,
FACTORY_START_PENDING,
FACTORY_HOLD_PENDING,
FACTORY_CANCEL_PENDING
};

struct RESEARCH;

struct RESEARCH_FACILITY
{
RESEARCH * psSubject; // The subject the structure is working on.
RESEARCH * psSubjectPending; // The subject the structure is going to work on when the GAME_RESEARCHSTATUS message is received.
StatusPending statusPending; ///< Pending = not yet synchronised.
unsigned pendingCount; ///< Number of messages sent but not yet processed.
UDWORD capacity; /* Number of upgrade modules added*/
UDWORD timeStarted; /* The time the building started on the subject*/
UDWORD researchPoints; /* Research Points produced per research cycle*/
RESEARCH * psBestTopic; // The topic with the most research points that was last performed
UDWORD timeStartHold; /* The time the research facility was put on hold*/
};

enum FACTORY_STATUS_PENDING
{
FACTORY_NOTHING_PENDING = 0,
FACTORY_START_PENDING,
FACTORY_HOLD_PENDING,
FACTORY_CANCEL_PENDING
};

struct DROID_TEMPLATE;

struct FACTORY
Expand All @@ -183,7 +185,7 @@ struct FACTORY
Build Cycle*/
DROID_TEMPLATE * psSubject; ///< The subject the structure is working on.
DROID_TEMPLATE * psSubjectPending; ///< The subject the structure is going to working on. (Pending = not yet synchronised.)
FACTORY_STATUS_PENDING statusPending; ///< Pending = not yet synchronised.
StatusPending statusPending; ///< Pending = not yet synchronised.
unsigned pendingCount; ///< Number of messages sent but not yet processed.

UDWORD timeStarted; /* The time the building started on the subject*/
Expand Down