[C++-sig] Boost Python loss of values
Jay Riley
super24bitsound at hotmail.com
Thu Aug 25 13:17:34 CEST 2011
I'm having a really weird issue in boost python. I'm focusing on a particular property/method to simplify the example. Here's the situation:
In my program, I have a class called Attack. With the following layout (simplified for example)
class Attack : public Action
{
public:
virtual int CalculateDamage(const std::vector<BattleCharacter*>& users, BattleCharacter* target, const std::vector<Actions::ActionTarget>& targets, BattleField *field);
protected:
bool Hit;
}
I exposed Attack to python, making it overridable, as follows:
struct AttackWrapper : Game::Battles::Actions::Attack
{
int AttackWrapper::CalculateDamage(const std::vector<Game::Battles::BattleCharacter*>& users, Game::Battles::BattleCharacter* target, const std::vector<Actions::ActionTarget>& targets, Game::Battles::BattleField *field)
{
return call_method<int>(self, "CalculateDamage", users, ptr(target), targets, ptr(field));
}
int AttackWrapper::CalculateDamageDefault(const std::vector<Game::Battles::BattleCharacter*>& users, Game::Battles::BattleCharacter* target, const std::vector<Actions::ActionTarget>& targets, Game::Battles::BattleField *field)
{
return this->Attack::CalculateDamage(users, target, Targets, field);
}
}
And the python exposing is done as follows:
class_<Attack, AttackWrapper, boost::shared_ptr<Attack>, bases<Action> >("Attack")
.def("CalculateDamage", &AttackWrapper::CalculateDamageDefault);
I initially thought everything was working fine, as I can override the `CalculateDamage` method within python and have it work correctly. However, When I want to use the normal `Attack->CalculateDamage`, the following happens:
I only call `CalculateDamage` when Hit is true, and I can confirm via break point when I hit this line, Hit is true:
return call_method<int>(self, "CalculateDamage", users, ptr(target), targets, ptr(field));
Now, because I haven't overriden `CalculateDamage` in Python for this attack instance, it ends up resolving to `AttackWrapper::CalculateDamageDefault`. But by the time I enter AttackWrapper::CalculateDamageDefault, Hit is no longer true. That is, when I break on this line:
return this->Attack::CalculateDamage(users, target, Targets, field);
Hit is false. So somewhere between
return call_method<int>(self, "CalculateDamage", users, ptr(target), targets, ptr(field));
resolving to
return this->Attack::CalculateDamage(users, target, Targets, field);
my property's value is lost. I have no idea what could be causing this. Has anyone encountered something like this before?
The attacks I'm using for testing are defined as follows:
class ScriptedAttack(Attack):
def __init__(self, Type, ID, Name, Flags, Targs = ActionTargets.Any, AllowTargettingOverride = False, Power = 0, MPCost = 0, SPCost = 0, Accuracy = 0.9, CritChance = 0.1, DefineOwnUse = False, EleWeights = None, StatusEffectChances = None):
if (EleWeights == None and StatusEffectChances == None):
Attack.__init__(self, Type, ID, Name, Flags, Targs, AllowTargettingOVerride, Power, MPCost, SPCost, Accuracy, CritChance, DefineOwnUse)
else:
Elemap = ElementMap()
if (EleWeights != None):
for Element, Weight in EleWeights.iteritems():
Elemap[Element] = Weight
SEChances = SEChanceMap()
if (StatusEffectChances != None):
for StatusEffect, Chance in StatusEffectChances.iteritems():
SEChances[StatusEffect] = Chance
Attack.__init__(self, Type, ID, Name, Flags, Elemap, Targs, AllowTargettingOverride, Power, MPCost, SPCost, Accuracy, CritChance, DefineOwnUse, SEChances)
def Clone(self):
return copy.deepcopy(self)
Fire = ScriptedAttack(ActionType.MagicAction, PrimaryEngine.GetUID(), "Fire", AttackFlags.Projectile | AttackFlags.Elemental, ActionTargets.Any, True, 32, 14, 0, 1.0, 0.1, False, {Elements.Fire: 1.0})
Fira = ScriptedAttack(ActionType.MagicAction, PrimaryEngine.GetUID(), "Fira", AttackFlags.Projectile | AttackFlags.Elemental, ActionTargets.Any, True, 63, 35, 0, 1.0, 0.1, False, {Elements.Fire: 1.0})
ActLibrary.AddAttack(Fire)
ActLibrary.AddAttack(Fira)
ActLibrary.AddAttack takes in a boost::shared_ptr<Attack> and stores it into a hash table. I lookup the attack and use the instance stored there to do CalculateDamage.
It almost seems like the object is being copied, but I have no idea why that'd be so.
Any help would be appreciated.
Thanks
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20110825/f9b21d5b/attachment.html>
More information about the Cplusplus-sig
mailing list