1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#ifndef OBJECT_H
#define OBJECT_H
#include <map>
#include <set>
#include "System/Platform/Threading.h"
#include "System/creg/creg_cond.h"
class CObject
{
public:
CR_DECLARE(CObject);
//FIXME why different depType's (it's not used anywhere currently except as a std::map key?!)
enum DependenceType {
DEPENDENCE_ATTACKER,
DEPENDENCE_BUILD,
DEPENDENCE_BUILDER,
DEPENDENCE_CAPTURE,
DEPENDENCE_COBTHREAD,
DEPENDENCE_COMMANDQUE,
DEPENDENCE_DECOYTARGET,
DEPENDENCE_INCOMING,
DEPENDENCE_INTERCEPT,
DEPENDENCE_INTERCEPTABLE,
DEPENDENCE_INTERCEPTTARGET,
DEPENDENCE_LANDINGPAD,
DEPENDENCE_LASTCOLWARN,
DEPENDENCE_LIGHT,
DEPENDENCE_ORDERTARGET,
DEPENDENCE_RECLAIM,
DEPENDENCE_REPULSE,
DEPENDENCE_REPULSED,
DEPENDENCE_RESURRECT,
DEPENDENCE_SELECTED,
DEPENDENCE_SOLIDONTOP,
DEPENDENCE_TARGET,
DEPENDENCE_TARGETUNIT,
DEPENDENCE_TERRAFORM,
DEPENDENCE_TRANSPORTEE,
DEPENDENCE_TRANSPORTER,
DEPENDENCE_WAITCMD,
DEPENDENCE_WEAPON,
DEPENDENCE_WEAPONTARGET
};
CObject();
virtual ~CObject();
void Serialize(creg::ISerializer* ser);
void PostLoad();
virtual void Detach();
/// Request to not inform this when obj dies
virtual void DeleteDeathDependence(CObject* obj, DependenceType dep);
/// Request to inform this when obj dies
virtual void AddDeathDependence(CObject* obj, DependenceType dep);
/// Called when an object died, that this is interested in
virtual void DependentDied(CObject* obj);
/*
// Possible future replacement for dynamic_cast (10x faster)
// Identifier bits for classes that have subclasses
enum {WORLDOBJECT_BIT=8,SOLIDOBJECT_BIT,UNIT_BIT,BUILDING_BIT,MOVETYPE_BIT,AAIRMOVETYPE_BIT,
COMMANDAI_BIT,EXPGENSPAWNABLE_BIT,PROJECTILE_BIT,SMOKEPROJECTILE_BIT,WEAPON_BIT};
// Class hierarchy for the relevant classes
enum {
OBJECT=0,
WORLDOBJECT=(1<<WORLDOBJECT_BIT),
SOLIDOBJECT=(1<<SOLIDOBJECT_BIT)|WORLDOBJECT,
FEATURE,
UNIT=(1<<UNIT_BIT)|SOLIDOBJECT,
BUILDER,TRANSPORTUNIT,
BUILDING=(1<<BUILDING_BIT)|UNIT,
FACTORY,EXTRACTORBUILDING,
MOVETYPE=(1<<MOVETYPE_BIT),
GROUNDMOVETYPE,
AAIRMOVETYPE=(1<<AAIRMOVETYPE_BIT)|MOVETYPE,
AIRMOVETYPE,
TAAIRMOVETYPE,
COMMANDAI=(1<<COMMANDAI_BIT),
FACTORYCAI,TRANSPORTCAI,MOBILECAI,
EXPGENSPAWNABLE=(1<<EXPGENSPAWNABLE_BIT),
PROJECTILE=(1<<PROJECTILE_BIT)|EXPGENSPAWNABLE,
SHIELDPARTPROJECTILE,
SMOKEPROJECTILE=(1<<SMOKEPROJECTILE_BIT)|PROJECTILE,
GEOTHERMSMOKEPROJECTILE,
WEAPON=(1<<WEAPON_BIT),
DGUNWEAPON,BEAMLASER
};
// Must also set objType in the contstructors of all classes that need to use this feature
unsigned objType;
#define INSTANCE_OF_SUBCLASS_OF(type,obj) ((obj->objType & kind) == kind) // exact class or any subclass of it
#define INSTANCE_OF(type,obj) (obj->objType == type) // exact class only, saves one instruction yay :)
*/
private:
// Note, this has nothing to do with the UnitID, FeatureID, ...
// It's only purpose is to make the sorting in TSyncSafeSet syncsafe
boost::int64_t sync_id;
static Threading::AtomicCounterInt64 cur_sync_id;
// makes std::set<T*> syncsafe (else iteration order depends on the pointer's address, which is not syncsafe)
struct syncsafe_compare
{
bool operator() (const CObject* const& a1, const CObject* const& a2) const
{
// I don't think the default less-op is sync-safe
//return a1 < a2;
return a1->sync_id < a2->sync_id;
}
};
public:
typedef std::set<CObject*, syncsafe_compare> TSyncSafeSet;
typedef std::map<DependenceType, TSyncSafeSet> TDependenceMap;
protected:
const TSyncSafeSet& GetListeners(const DependenceType dep) { return listeners[dep]; }
const TDependenceMap& GetAllListeners() const { return listeners; }
const TSyncSafeSet& GetListening(const DependenceType dep) { return listening[dep]; }
const TDependenceMap& GetAllListening() const { return listening; }
protected:
bool detached;
TDependenceMap listeners;
TDependenceMap listening;
};
#endif /* OBJECT_H */
|