Okay I think something else is majorly wrong; my component objects are being
seen at Item onjects. I'll try to keep the code I show to a minimum.
In my python file, I have the following:
def ItemFactory(ItemNode): ItemName = ItemNode.attrib["name"] if (True):
#if ItemName == "Elixir": CurrentItem = Item(ItemName) print
ItemName componentNode = ItemNode.find("Components"); if
(componentNode != None): components = componentNode.getchildren()
for component in components: if component.tag ==
"HealingComponent": healer = UseComponent("HealUseModule",
True, True) print "Adding Healing Component"
CurrentItem.RegisterComponent("Healing Component", healer)
ItemModule.ItemLibrary.AddItem(CurrentItem)
ItemNode is just an XML node that I parse for properties. Each Item node gets
sent to this function. As per Jim's advice, RegisterComponent looks as follows:
void RegisterComp(Items::Item& item, const std::string& compName,
std::auto_ptr<UseComponentWrap> comp)//, void* comp){
item.RegisterComponent(compName, comp.get()); comp.release();}
Now, the components are registering. The problem is, when I try do the
following:
try { boost::shared_ptr<Items::Item> item =
Game.GetItemLibrary().GetItem("Elixir"); Components::Component* heal =
item->GetComponent("Healing Component");
Components::UseComponent* healertrue =
dynamic_cast<Components::UseComponent*>(heal); if (healertrue !=
nullptr)
healertrue->Use(std::vector<Character::BaseCharacter*>(),
std::vector<Character::BaseCharacter*>()); } catch
(boost::python::error_already_set) { PyErr_Print(); }
it prints out this error:
AttributeError: 'Item' object has no attribute 'Use'
this is really confusing. How could my UseComponent have become an Item?
I was testing it, and set the AddItem function as:
static std::vector<Components::Component*> test;void
ItemDatabase::AddItem(boost::shared_ptr<Item> item) { if
(item.get() != nullptr) {
IDToItemMap[item->GetID()] = item;
NameToItemMap[item->GetName()] = item; auto healComp =
item->GetComponent("Healing Component"); if (healComp !=
nullptr) {
test.push_back(healComp); int x = 10;
} } }
Here's the weird thing. While I'm adding items, I used x = 10 as a breakpoint
to watch healComp's be added to test. The first healComp get's inserted
correctly, and the PyObject's tp_name says UseComponent. When the second item
with a healComp is being added, I used the vector to check the first healComp
inserted and it somehow became an item (tp_name says Item). This is really
weird. I thought it might be a scoping problem in my python code, but I can't
see anything wrong with it. I'm not sure if it's relevant, but I'm including my
UseComponent wrapping
//Class definitionclass UseComponentWrap : public Components::UseComponent
{ public: UseComponentWrap(PyObject*
self_); UseComponentWrap(PyObject* self_, const
std::string& name, bool hasUse, bool hasBattleUse);
UseComponentWrap(PyObject* self_, const Components::UseComponent& cmp);
bool Use(std::vector<Character::BaseCharacter*>& Users,
std::vector<Character::BaseCharacter*>& Targets) override;
bool UseDefault(std::vector<Character::BaseCharacter*>& Users,
std::vector<Character::BaseCharacter*>& Targets); bool
BattleUse(std::vector<Battle::BattleCharacter*>& Users,
std::vector<Battle::BattleCharacter*>& Targets, Battle::BattleField* field)
override; bool
BattleUseDefault(std::vector<Battle::BattleCharacter*>& Users,
std::vector<Battle::BattleCharacter*>& Targets, Battle::BattleField* field);
Components::UseComponent::ClonePtr Clone() const override;
Components::UseComponent::ClonePtr CloneDefault() const;
PyObject* self;
private:
};
//Python Wrapping
class_<Components::UseComponent, std::auto_ptr<UseComponentWrap>,
bases<Components::Component> >("UseComponent")
.def(init<>()) .def(init<const std::string&,bool,
bool>()) .def(init<const
Components::UseComponent&>()) .def("BattleUse",
&Components::UseComponent::BattleUse, &UseComponentWrap::BattleUseDefault)
.def("Use", &Components::UseComponent::Use,
&UseComponentWrap::UseDefault) .def("HasUse",
&Components::UseComponent::HasUse)
.def("HasBattleUse", &Components::UseComponent::HasBattleUse)
.def("Clone", &Components::UseComponent::Clone,
&UseComponentWrap::CloneDefault,
return_value_policy<reference_existing_object>())
.def("__copy__", &generic__copy__<Components::UseComponent>)
.def("__deepcopy__", &generic__deepcopy__<Components::UseComponent>)
;
I really don't see how this can get turned into an Item, Any ideas?
Thanks for the help so far
> Date: Tue, 8 Nov 2011 11:02:23 -0500
> From: [email protected]
> To: [email protected]
> Subject: Re: [C++-sig] Passing ownership to C++ through pointer
>
> On 11/08/2011 01:12 AM, Jay Riley wrote:
> > I'm trying to pass an object from python to C++. I want C++ to take
> > control of the object.
>
> <snip>
>
> > Am I doing something wrong? base on that snippet it should work. Is
> > there another way to do this? I know I should probably switch to
> > smart_ptrs and I'm considering it, but Id like to be able to know how to
> > do this, even if its just for future reference. Any help would be
> > appreciated.
> >
>
> I suspect the inheritance is getting in the way, and Boost.Python isn't
> being as smart as it could be about converting auto_ptr<T> to
> auto_ptr<U> when T* is convertible to U*.
>
> You might want to try having your register function wrapper accept
> auto_ptr<UseComponentWrap> (and if necessary, providing an overload that
> takes auto_ptr<UseComponent>).
>
> Before that, however, you might want to just try using "auto_ptr &"
> rather than simple "auto_ptr". It'd be unfortunate if that was
> necessary, but it's a possibility.
>
> Good luck!
>
> Jim
> _______________________________________________
> Cplusplus-sig mailing list
> [email protected]
> http://mail.python.org/mailman/listinfo/cplusplus-sig
_______________________________________________
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig