template<class ObjectClass, class StaticType>
class TMemberSnapshotValue : public TStaticValue<StaticType>,
public EventTargetContainer<TMemberSnapshotValue<ObjectClass, StaticType> >
{
private:
typedef StaticType (ObjectClass::*PFNMember)();
TRef<ObjectClass> m_pobject;
PFNMember m_pfn;
public:
TMemberSnapshotValue(ObjectClass* pobject,
PFNMember pfn, IEventSource* peventSource,
const StaticType& value) :
TStaticValue<StaticType>(value),
m_pobject(pobject),
m_pfn(pfn)
{
ZAssert(pobject != NULL);
ZAssert(pfn != NULL);
AddEventTarget(&TMemberSnapshotValue<ObjectClass,StaticType>::OnEvent, peventSource);
}
bool OnEvent()
{
StaticType value = (m_pobject->*m_pfn)();
if (GetValueInternal() != value)
{
GetValueInternal() = value;
Changed();
}
return true;
}
};
template<class ObjectClass, class StaticType>
class TMemberSnapshotValueFactory : public IFunction
{
private:
typedef StaticType (ObjectClass::*PFNMember)();
typedef TMemberSnapshotValue<ObjectClass, StaticType> MemberSnapshotValue;
PFNMember m_pfn;
StaticType m_value;
public:
TMemberSnapshotValueFactory(PFNMember pfn, const StaticType& value) :
m_pfn(pfn),
m_value(value)
{
}
TRef<IObject> Apply(ObjectStack& stack)
{
TRef<ObjectClass> pobject; CastTo(pobject, (IObject*)stack.Pop());
TRef<IEventSource> peventSource; CastTo(peventSource, (IObject*)stack.Pop());
return (TStaticValue<StaticType>*) new MemberSnapshotValue(pobject, m_pfn, peventSource, m_value);
}
};
class ModelWrapper : public TrekClientEventSink
{
protected:
TRef<ImodelIGC> m_pmodel;
TRef<EventSourceImpl> m_peventSourceOnChange;
public:
ModelWrapper() :
m_peventSourceOnChange(new EventSourceImpl())
{
}
ModelWrapper(ImodelIGC* pmodel) :
m_pmodel(pmodel),
m_peventSourceOnChange(new EventSourceImpl())
{
}
ImodelIGC* GetModel()
{
return m_pmodel;
}
void SetModel(ImodelIGC* pmodel)
{
if (m_pmodel == pmodel)
return;
m_pmodel = pmodel;
m_peventSourceOnChange->Trigger();
}
void OnModelTerminated(ImodelIGC* pmodel)
{
if (pmodel == m_pmodel)
SetModel(NULL);
}
void OnTechTreeChanged(SideID sid)
{
if (m_pmodel && m_pmodel->GetSide() && m_pmodel->GetSide()->GetObjectID() == sid
&& m_pmodel->GetObjectType() == OT_station)
{
m_peventSourceOnChange->Trigger();
}
}
IEventSource* GetOnChangeEventSource()
{
return m_peventSourceOnChange;
}
};
class ModelData : public ModelWrapper
{
private:
IshipIGC* GetShip()
{ ZAssert(GetModelTypeInternal() == OT_ship); return ((IshipIGC*)(ImodelIGC*)m_pmodel)->GetSourceShip(); }
IstationIGC* GetStation()
{ ZAssert(GetModelTypeInternal() == OT_station); return (IstationIGC*)(ImodelIGC*)m_pmodel; }
IasteroidIGC* GetAsteroid()
{ ZAssert(GetModelTypeInternal() == OT_asteroid); return (IasteroidIGC*)(ImodelIGC*)m_pmodel; }
IprobeIGC* GetProbe()
{ ZAssert(GetModelTypeInternal() == OT_probe); return (IprobeIGC*)(ImodelIGC*)m_pmodel; }
ObjectType GetModelTypeInternal();
public:
ModelData(){};
ModelData(ImodelIGC* pmodel) : ModelWrapper(pmodel) {};
ImodelIGC* GetModel();
float GetModelType();
ZString GetModelTypeDesc();
TRef<Image> GetModelTypeIcon();
ZString GetName();
ZString GetSectorName();
ZString GetSideName();
Color GetSideColor();
TRef<Image> GetSideIcon();
float GetSpeed();
float GetMass();
float GetRange();
float GetPercentHitPoints();
float GetPercentShields();
float GetPercentEnergy();
float GetAmmo();
float GetFuel();
float GetOre();
float GetVectorLock();
float GetCloaking();
float GetSignature();
float GetNumObservers();
float GetRipcordTimeLeft();
float GetEndurance();
float IsCloaked();
float IsEjectPod();
float IsRipcording();
bool IsVisible();
bool IsNotNull();
static void ExportAccessors(INameSpace* pns)
{
pns->AddMember("GetModelType", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetModelType, (float)OT_invalid));
pns->AddMember("GetModelTypeDesc", new TMemberSnapshotValueFactory<ModelData, ZString>(&ModelData::GetModelTypeDesc, ""));
pns->AddMember("GetName", new TMemberSnapshotValueFactory<ModelData, ZString>(&ModelData::GetName, ""));
pns->AddMember("GetSectorName", new TMemberSnapshotValueFactory<ModelData, ZString>(&ModelData::GetSectorName, ""));
pns->AddMember("GetSideName", new TMemberSnapshotValueFactory<ModelData, ZString>(&ModelData::GetSideName, ""));
pns->AddMember("GetSideColor", new TMemberSnapshotValueFactory<ModelData, Color>(&ModelData::GetSideColor, Color(255,255,255)));
pns->AddMember("GetSpeed", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetSpeed, 0.0f));
pns->AddMember("GetMass", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetMass, 0.0f));
pns->AddMember("GetRange", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetRange, 0.0f));
pns->AddMember("GetPercentHitPoints", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetPercentHitPoints, 0.0f));
pns->AddMember("GetPercentShields", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetPercentShields, 0.0f));
pns->AddMember("GetPercentEnergy", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetPercentEnergy, 0.0f));
pns->AddMember("GetAmmo", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetAmmo, 0.0f));
pns->AddMember("GetFuel", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetFuel, 0.0f));
pns->AddMember("GetOre", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetOre, 0.0f));
pns->AddMember("GetVectorLock", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetVectorLock, 0.0f));
pns->AddMember("GetCloaking", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetCloaking, 0.0f));
pns->AddMember("GetNumObservers", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetNumObservers, 0.0f));
pns->AddMember("GetSignature", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetSignature, 0.0f));
pns->AddMember("GetRipcordTimeLeft", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetRipcordTimeLeft, 0.0f));
pns->AddMember("GetEndurance", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::GetEndurance, 1.0f));
pns->AddMember("IsCloaked", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::IsCloaked, 0.0f));
pns->AddMember("IsEjectPod", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::IsEjectPod, 0.0f));
pns->AddMember("IsRipcording", new TMemberSnapshotValueFactory<ModelData, float>(&ModelData::IsRipcording, 0.0f));
pns->AddMember("IsVisible", new TMemberSnapshotValueFactory<ModelData, bool>(&ModelData::IsVisible, false));
pns->AddMember("IsNotNull", new TMemberSnapshotValueFactory<ModelData, bool>(&ModelData::IsNotNull, false));
}
};
class PartWrapper : public IObject
{
protected:
TRef<IpartIGC> m_ppart;
TRef<EventSourceImpl> m_peventSourceOnChange;
private:
public:
PartWrapper() :
m_peventSourceOnChange(new EventSourceImpl())
{
}
PartWrapper(IpartIGC* ppart) :
m_ppart(ppart),
m_peventSourceOnChange(new EventSourceImpl())
{
}
IpartIGC* GetPart()
{
return m_ppart;
}
void SetPart(IpartIGC* ppart)
{
if (m_ppart == ppart)
return;
m_ppart = ppart;
m_peventSourceOnChange->Trigger();
}
IEventSource* GetOnChangeEventSource()
{
return m_peventSourceOnChange;
}
ZString GetPartName();
float GetCount();
float GetRange();
float GetDamage();
float GetRate();
float GetAfterburnerFuelConsumption();
float GetAfterburnerFuelLeft();
float GetAfterburnerTopSpeed();
float GetAfterburnerTimeLeft();
float GetMaxShieldStrength();
float GetShieldStrength();
float GetRegenRate();
float GetRechargeTime();
float GetCloakTimeLeft();
float IsEnergyDamage();
float IsShipKiller();
float IsStationKiller();
float IsAsteroidKiller();
float IsSelected();
float IsActive();
float IsOutOfAmmo();
float GetReadyState();
float GetMountedFraction();
float GetArmedFraction();
static void ExportAccessors(INameSpace* pns)
{
pns->AddMember("GetPartName", new TMemberSnapshotValueFactory<PartWrapper, ZString>(&PartWrapper::GetPartName, ""));
pns->AddMember("GetCount", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetCount, 1.0f));
pns->AddMember("GetWeaponRange", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetRange, 0.0f));
pns->AddMember("GetDamage", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetDamage, 0.0f));
pns->AddMember("GetRate", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetRate, 0.0f));
pns->AddMember("GetAfterburnerFuelConsumption", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetAfterburnerFuelConsumption, 0.0f));
pns->AddMember("GetAfterburnerFuelLeft", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetAfterburnerFuelLeft, 0.0f));
pns->AddMember("GetAfterburnerTopSpeed", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetAfterburnerTopSpeed, 0.0f));
pns->AddMember("GetAfterburnerTimeLeft", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetAfterburnerTimeLeft, 0.0f));
pns->AddMember("GetMaxShieldStrength", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetMaxShieldStrength, 0.0f));
pns->AddMember("GetShieldStrength", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetShieldStrength, 0.0f));
pns->AddMember("GetRegenRate", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetRegenRate, 0.0f));
pns->AddMember("GetRechargeTime", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetRechargeTime, 0.0f));
pns->AddMember("GetCloakTimeLeft", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetCloakTimeLeft, 0.0f));
pns->AddMember("IsEnergyDamage", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::IsEnergyDamage, 0.0f));
pns->AddMember("IsSelected", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::IsSelected, 0.0f));
pns->AddMember("IsShipKiller", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::IsShipKiller, 0.0f));
pns->AddMember("IsStationKiller", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::IsStationKiller, 0.0f));
pns->AddMember("IsAsteroidKiller", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::IsAsteroidKiller, 0.0f));
pns->AddMember("IsActive", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::IsActive, 0.0f));
pns->AddMember("IsOutOfAmmo", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::IsOutOfAmmo, 0.0f));
pns->AddMember("GetReadyState", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetReadyState, 0.0f));
pns->AddMember("GetMountedFraction", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetMountedFraction, 0.0f));
pns->AddMember("GetArmedFraction", new TMemberSnapshotValueFactory<PartWrapper, float>(&PartWrapper::GetArmedFraction, 0.0f));
}
};