I've been looking around and I can find tons of information about how to wrap 
shallow inheritance hierarchys with virtual/pure virtual functions, but none of 
them show how to do multi level inheritance. I'm unsure if I'm supposed to 
inherit from the wrapper or the base class for the virtual functions. 
Essentially, I'm asking what the best way to wrap this, the various methods 
I've tried usually result in error messages about the wrapper not being 
available
For Instance I have this hierarchy:
class DrawInterface     {       public:         DrawInterface(int drawPriority 
= 0, bool drawing = true) : DrawPriority(drawPriority), Drawing(drawing)        
 {
                }               bool IsDrawing() const          {               
        return Drawing;         }               void SetDrawing(const bool 
value)               {                       Drawing = value;                }  
             virtual void Draw(sf::RenderWindow &window) = 0;                
virtual void Draw(sf::RenderWindow &window, sf::Shader &shader) = 0;            
int GetDrawPriority() const             {                       return 
DrawPriority;            }       private:                bool Drawing;          
 int DrawPriority;       };
class AnimatedDraw : public DrawInterface       {       public:         
AnimatedDraw(bool paused = false, int drawPriority = 0) : 
DrawInterface(drawPriority), Paused(paused)           {               }         
                      virtual void Update(const sf::Uint32 time, const float 
TimeScale = 1.0) = 0;            virtual void Update(const float time, const 
float TimeScale = 1.0) = 0;         virtual void SetPause(const bool value)     
    {                       Paused = value;         }               virtual 
bool GetPause() const           {                       return Paused;          
}       protected:              bool Paused;    private:        };
class InputInterface    {       public:         InputInterface(bool 
acceptingInputs = true) : AcceptingInputs(acceptingInputs)          {
                }               bool IsAcceptingInputs() const          {       
                return AcceptingInputs;         }               void 
SetAcceptingInputs(const bool value)               {                       
AcceptingInputs = value;                }               virtual bool 
HandleKeyPressed(const sf::Uint32 time, const ::Input::InputModule* 
inputModule, ::Input::PlayerInput pInput, ::Input::InputAction& action) { 
return false;}               virtual bool HandleKeyReleased(const sf::Uint32 
time, const ::Input::InputModule* inputModule, ::Input::PlayerInput pInput, 
::Input::InputAction& action) { return false;}      private:                
bool AcceptingInputs;   };
class Screen : public ::Input::InputInterface, public AnimatedDraw              
{               public:                 Screen(const std::string& name, 
::Engine* engine, int id);                      int GetID() const;              
        const std::string& GetScreenName() const;                       void 
SetScreenName(const std::string& name);
                        bool AddOwner(const std::string& name, ScreenStack* 
stack);                     bool RemoveOwner(const std::string& name);          
            bool HasOwner(const std::string& name) const;                   
const boost::unordered_map<std::string, ScreenStack*>& GetOwners() const;
                        bool operator==(const Screen& screen) const;            
        bool operator!=(const Screen& screen) const;            private:        
                Engine* engine;                 int ScreenID;                   
std::string ScreenName;                 sf::Uint32 LastUpdate;                  
boost::unordered_map<std::string, ScreenStack*> OwningStacks;
                        friend class ScreenManager;             };
I want to be able to create various types of screens in Python so obviously I 
need to expose/wrap all the base classes, but this is where I get a little 
unclear about if I should be inheriting from the wrappers or the base classes, 
and how I should be representing these clases in python. My initial attempt at 
wrapping looked something like this:
class DrawInterfaceWrap : public DrawInterface  {       public:         
DrawInterfaceWrap(PyObject* self, int priority = 0, bool drawing = true) : 
self(self), DrawInterface(priority, drawing)         {
                }               DrawInterfaceWrap(PyObject* self, const 
DrawInterface& src) : self(self), DrawInterface(src)            {
                }               void Draw(sf::RenderWindow &window) override    
        {                       call_method<void>(self, "Draw", 
boost::ref(window));            }               void Draw(sf::RenderWindow 
&window, sf::Shader& shader) override                {                       
call_method<void>(self, "Draw", boost::ref(window), boost::ref(shader));        
        }       private:                PyObject* self; };
        class AnimatedDrawWrap : public AnimatedDraw    {       public:         
AnimatedDrawWrap(PyObject* self, int priority = 0, bool paused = true) : 
self(self), AnimatedDraw(paused, priority)             {
                }               //??? not sure how to do ta proper copy 
construction on self            AnimatedDrawWrap(PyObject* self, const 
AnimatedDraw& src) : self(self), AnimatedDraw(src)               {
                }               void Update(const sf::Uint32 time, const float 
TimeScale = 1.0) override                {                       
call_method<void>(self, "Update", time, TimeScale);             }               
void Update(float time, const float TimeScale = 1.0) override           {       
                call_method<void>(self, "Update", time, TimeScale);             
                        }       private:                PyObject* self; };
class_<DrawInterfaceWrap>("DrawInterface", init<boost::python::optional<int, 
bool> >())                 .def(init<const DrawInterface&>())                   
   .def("Draw", pure_virtual((void 
(DrawInterface::*)(sf::RenderWindow&))&DrawInterface::Draw))                    
.def("Draw", pure_virtual((void (DrawInterface::*)(sf::RenderWindow&, 
sf::Shader&))&DrawInterface::Draw))                       .def("IsDrawing", 
&DrawInterface::IsDrawing)                    .def("SetDrawing", 
&DrawInterface::SetDrawing)                  .def("GetDrawPriority", 
&DrawInterface::GetDrawPriority)                        ;               
class_<AnimatedDrawWrap, bases<DrawInterfaceWrap> >("AnimatedDraw", 
init<boost::python::optional<int, bool> >())                        
.def(init<const AnimatedDraw&>())                       .def(init<const 
AnimatedDrawWrap&>())                   .def("Update", pure_virtual((void 
(AnimatedDraw::*)(const sf::Uint32, const float))&AnimatedDraw::Update))        
              .def("Update", pure_virtual((void (AnimatedDraw::*)(const float, 
const float))&AnimatedDraw::Update))                   .def("GetPause", 
&AnimatedDraw::GetPause)                       .def("SetPause", 
&AnimatedDraw::SetPause)                       ;
class InputInterfaceWrap : public ::Input::InputInterface       {       public: 
        InputInterfaceWrap(PyObject* self, bool acceptingInputs = true) : 
self(self), ::Input::InputInterface(acceptingInputs)          {               }
                virtual bool HandleKeyPressed(const sf::Uint32 time, const 
::Input::InputModule* inputModule, ::Input::PlayerInput pInput, 
::Input::InputAction& action) override               {                       
return call_method<bool>(self, "HandleKeyPressed", time, ptr(inputModule), 
pInput, boost::ref(action));         }               virtual bool 
HandleKeyReleased(const sf::Uint32 time, const ::Input::InputModule* 
inputModule, ::Input::PlayerInput pInput, ::Input::InputAction& action) 
override              {                       return call_method<bool>(self, 
"HandleKeyReleased", time, ptr(inputModule), pInput, boost::ref(action));       
         }       private:                PyObject* self; };
class_<InputInterfaceWrap, boost::noncopyable>("InputInteface", 
init<boost::python::optional<bool> >())                 
.def("HandleKeyPressed", 
pure_virtual(&::Input::InputInterface::HandleKeyPressed))                      
.def("HandleKeyReleased", 
pure_virtual(&::Input::InputInterface::HandleKeyReleased))                    
.def("IsAcceptingInputs", &::Input::InputInterface::IsAcceptingInputs)          
        .def("SetAcceptingInputs", 
&::Input::InputInterface::SetAcceptingInputs)                        ;
class_<Screen, bases<Graphics::AnimatedDraw, ::Input::InputInterface> 
>("Screen", init<const std::string&, ::Engine*, int>())                   
.def("GetID", &Screen::GetID)                   .def("GetScreenName", 
&Screen::GetScreenName, return_value_policy<reference_existing_object>())       
          .def("HasOwner", &Screen::HasOwner)                     
.def("RemoveOwner", &Screen::RemoveOwner)                       
.def("SetScreenName", &Screen::SetScreenName)                   ;
I cant export this wrapping because boost python won't let me have initializers 
for abstract classes. I attempted to fix this by changing all the pure virtual 
functions to virtual functions, and adding a Default method for each virtual 
function in the wrapper. I was able to compile like this, but python hits a 
runtime error saying a wrapper is unavailable for base class AnimatedDraw, so 
obviously my exports are sstill incorrect. I'm looking for advice on how to 
export this hierarchy. Can I keep these functions pure virtual and have 
initializers or will I need to add a default implementation? Further to that, 
should I be inheriting from the wrappers and not the base classes? I really 
just want this to work where I can inherit from Screen and implement Update, 
Draw and HandleKeys for each screen.
I had an additional question. How do you correctly implement a copy 
constructors on the wrapper classes?for instance 
this:AnimatedDrawWrap(PyObject* self, const AnimatedDraw& src) : self(self), 
AnimatedDraw(src)             {
                }
I assume is incorrect since I'm not making a proper copy of the self pointer. 
What's the correct way to do this?
My last question is more a sylistic one. I've seen multiple ways to implement 
the virtual function override. I've chosen the call_method form:
void Update(const sf::Uint32 time, const float TimeScale = 1.0) override        
        {                       call_method<void>(self, "Update", time, 
TimeScale);             }
just because that's what I'm used to. Is there a "better" or more correct way 
to do this? or is it a purely stylistic choice?
Sorry for the cluster of code, I hope my questions are clear. I can clean out 
some parts of the code that I don't think are relevant, but since the classes 
are fairly small to begin with, I figured it'd be okay.
Thanks on advance for any help :)                                         
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to