Page 1 of 1

[Solved] Help to reuse CEGUI classes

Posted: Sun Dec 26, 2010 19:10
by uelkfr
I'm creating own classes to handle objects loading from XML. And I decided to reuse CEGUI classes XMLAttributes, XMLHandler, XMLParser, XMLSerializer, NamedXMLResourceManager. To simplify task I have copied CEGUIImage.h, CEGUIImage.cpp, CEGUIImageset.h, CEGUIImageset.cpp, CEGUIImageset_xmlHandler.h, CEGUIImageset_xmlHandler.cpp, CEGUIImagesetManager.h, CEGUIImagesetManager.cpp to my src dir as a base for my own classes and started to adapt using Ctrl-H. But I get complier errors.

PGOperator.hpp

Code: Select all

#ifndef _PGOperator_hpp_
#define _PGOperator_hpp_

#include "CEGUIBase.h"
#include "CEGUIString.h"
#include "CEGUIRect.h"
#include "CEGUIColourRect.h"
#include "CEGUIVector.h"
#include "CEGUISize.h"
#include "CEGUIRenderer.h"
#include "CEGUIXMLSerializer.h"
#include "PGOperatorset.hpp"
#include <map>


#if defined(_MSC_VER)
#   pragma warning(push)
#   pragma warning(disable : 4251)
#endif


// Start of ProcGen namespace section
namespace ProcGen
{
/*!
\brief
   Class that represents a single Operator of an Operatorset.
*/
class Operator
{
public:
   /*!
   \brief
      Return a CEGUI::Size object containing the dimensions of the Image.

   \return
       CEGUI::Size object holding the width and height of the Image.
   */
    CEGUI::Size   getSize(void) const         {return CEGUI::Size(d_scaledWidth, d_scaledHeight);}
   

   /*!
   \brief
      Return the pixel width of the image.

   \return
      Width of this Image in pixels.
   */
   float   getWidth(void) const      {return d_scaledWidth;}


   /*!
   \brief
      Return the pixel height of the image.

   \return
      Height of this Image in pixels
   */
   float   getHeight(void) const      {return d_scaledHeight;}


   /*!
   \brief
      Return a CEGUI::Point object that contains the offset applied when rendering this Image

   \return
       CEGUI::Point object containing the offsets applied when rendering this Image
   */
    CEGUI::Point   getOffsets(void) const      {return d_scaledOffset;}


   /*!
   \brief
      Return the X rendering offset

   \return
      X rendering offset.  This is the number of pixels that the image is offset by when rendering at any given location.
   */
   float   getOffsetX(void) const      {return   d_scaledOffset.d_x;}


   /*!
   \brief
      Return the Y rendering offset

   \return
      Y rendering offset.  This is the number of pixels that the image is offset by when rendering at any given location.
   */
   float   getOffsetY(void) const      {return d_scaledOffset.d_y;}


   /*!
   \brief
      Return the name of this Image object.

   \return
       CEGUI::String object containing the name of this Image
   */
   const CEGUI::String&   getName(void) const;


   /*!
   \brief
      Return the name of the Operatorset that contains this Image

   \return
       CEGUI::String object containing the name of the Operatorset which this Image is a part of.
   */
   const CEGUI::String&   getOperatorsetName(void) const;

   /*!
   \brief
      Return the parent Operatorset object that contains this Image

   \return
      The parent Operatorset object.
   */
   const Operatorset*   getOperatorset(void) const {return d_owner;}

    /*!
    \brief
        Return CEGUI::Rect describing the source texture area used by this Image.

    \return
        CEGUI::Rect object that describes, in pixels, the area upon the source texture
        which is used when rendering this Image.
    */
    const CEGUI::Rect& getSourceTextureArea(void) const;

    /*!
    \brief
        Queue the image to be drawn.

    \note
        The final position of the Image will be adjusted by the offset values
        defined for this Image object.  If absolute positioning is essential
        then these values should be taken into account prior to calling the
        draw() methods.  However, by doing this you take away the ability of the
        Operatorset designer to adjust the alignment and positioning of Images,
        therefore your component is far less useful since it requires code
        changes to modify image positioning that could have been handled from a
        data file.

    \param buffer
        GeometryBuffer object where the geometry for the image will be queued.

    \param position
        CEGUI::Vector2 object containing the location where the Image is to be drawn

    \param size
        CEGUI::Size object describing the size that the Image is to be drawn at.

    \param clip_rect
        CEGUI::Rect object that defines an on-screen area that the Image will be
        clipped to when drawing.

    \param top_left_colour
        Colour to be applied to the top-left corner of the Image.

    \param top_right_colour
        Colour to be applied to the top-right corner of the Image.

    \param bottom_left_colour
        Colour to be applied to the bottom-left corner of the Image.

    \param bottom_right_colour
        Colour to be applied to the bottom-right corner of the Image.

    \param quad_split_mode
        One of the CEGUI::QuadSplitMode values specifying the way the quad geometry for
        the image is to be split into triangles.

    \return
        Nothing
    */
    void draw(CEGUI::GeometryBuffer& buffer, const CEGUI::Vector2& position, const CEGUI::Size& size,
              const CEGUI::Rect* clip_rect,
              const CEGUI::colour& top_left_colour = 0xFFFFFFFF,
              const CEGUI::colour& top_right_colour = 0xFFFFFFFF,
              const CEGUI::colour& bottom_left_colour = 0xFFFFFFFF,
              const CEGUI::colour& bottom_right_colour = 0xFFFFFFFF,
              CEGUI::QuadSplitMode quad_split_mode = CEGUI::TopLeftToBottomRight) const
    {
        draw(buffer, CEGUI::Rect(position.d_x, position.d_y,
                          position.d_x + size.d_width,
                          position.d_y + size.d_height),
             clip_rect,
             CEGUI::ColourRect(top_left_colour, top_right_colour, bottom_left_colour,
                        bottom_right_colour),
             quad_split_mode);
    }

    /*!
    \brief
        Queue the image to be drawn.

    \note
        The final position of the Image will be adjusted by the offset values
        defined for this Image object.  If absolute positioning is essential
        then these values should be taken into account prior to calling the
        draw() methods.  However, by doing this you take away the ability of the
        Operatorset designer to adjust the alignment and positioning of Images,
        therefore your component is far less useful since it requires code
        changes to modify image positioning that could have been handled from a
        data file.

    \param buffer
        GeometryBuffer object where the geometry for the image will be queued.

    \param dest_rect
        CEGUI::Rect object defining the area on-screen where the Image is to be drawn.
        The Image will be scaled to fill the area as required.

    \param clip_rect
        CEGUI::Rect object that defines an on-screen area that the Image will be
        clipped to when drawing.

    \param top_left_colour
        Colour to be applied to the top-left corner of the Image.

    \param top_right_colour
        Colour to be applied to the top-right corner of the Image.

    \param bottom_left_colour
        Colour to be applied to the bottom-left corner of the Image.

    \param bottom_right_colour
        Colour to be applied to the bottom-right corner of the Image.

    \param quad_split_mode
        One of the CEGUI::QuadSplitMode values specifying the way the quad geometry for
        the image is to be split into triangles.

    \return
        Nothing
    */
    void draw(CEGUI::GeometryBuffer& buffer, const CEGUI::Rect& dest_rect,
              const CEGUI::Rect* clip_rect,
              const CEGUI::colour& top_left_colour = 0xFFFFFFFF,
              const CEGUI::colour& top_right_colour = 0xFFFFFFFF,
              const CEGUI::colour& bottom_left_colour = 0xFFFFFFFF,
              const CEGUI::colour& bottom_right_colour = 0xFFFFFFFF,
              CEGUI::QuadSplitMode quad_split_mode = CEGUI::TopLeftToBottomRight) const
    {
        draw(buffer, dest_rect, clip_rect,
             CEGUI::ColourRect(top_left_colour, top_right_colour,
                        bottom_left_colour, bottom_right_colour),
             quad_split_mode);
    }

    /*!
    \brief
        Queue the image to be drawn.

    \note
        The final position of the Image will be adjusted by the offset values
        defined for this Image object.  If absolute positioning is essential
        then these values should be taken into account prior to calling the
        draw() methods.  However, by doing this you take away the ability of the
        Operatorset designer to adjust the alignment and positioning of Images,
        therefore your component is far less useful since it requires code
        changes to modify image positioning that could have been handled from a
        data file.

    \param buffer
        GeometryBuffer object where the geometry for the image will be queued.

    \param position
        CEGUI::Vector2 object containing the location where the Image is to be drawn.

    \param size
        CEGUI::Size object describing the size that the Image is to be drawn at.

    \param clip_rect
        CEGUI::Rect object that defines an on-screen area that the Image will be
        clipped to when drawing.

    \param colours
        CEGUI::ColourRect object that describes the colour values to use for each
        corner of the Image.

    \param quad_split_mode
        One of the CEGUI::QuadSplitMode values specifying the way the quad geometry for
        the image is to be split into triangles.

    \return
        Nothing
    */
    void draw(CEGUI::GeometryBuffer& buffer, const CEGUI::Vector2& position, const CEGUI::Size& size,
              const CEGUI::Rect* clip_rect, const CEGUI::ColourRect& colours,
              CEGUI::QuadSplitMode quad_split_mode = CEGUI::TopLeftToBottomRight) const
    {
        draw(buffer, CEGUI::Rect(position.d_x, position.d_y,
                          position.d_x + size.d_width,
                          position.d_y + size.d_height),
             clip_rect, colours, quad_split_mode);
    }

    /*!
    \brief
        Queue the image to be drawn.

    \note
        The final position of the Image will be adjusted by the offset values
        defined for this Image object.  If absolute positioning is essential
        then these values should be taken into account prior to calling the
        draw() methods.  However, by doing this you take away the ability of the
        Operatorset designer to adjust the alignment and positioning of Images,
        therefore your component is far less useful since it requires code
        changes to modify image positioning that could have been handled from a
        data file.

    \param buffer
        GeometryBuffer object where the geometry for the image will be queued.

    \param position
        CEGUI::Vector2 object containing the location where the Image is to be drawn

    \note
        The image will be drawn at it's internally defined size.

    \param clip_rect
        CEGUI::Rect object that defines an on-screen area that the Image will be
        clipped to when drawing.

    \param colours
        CEGUI::ColourRect object that describes the colour values to use for each
        corner of the Image.

    \param quad_split_mode
        One of the CEGUI::QuadSplitMode values specifying the way the quad geometry for
        the image is to be split into triangles.

    \return
        Nothing
    */
    void draw(CEGUI::GeometryBuffer& buffer, const CEGUI::Vector2& position,
              const CEGUI::Rect* clip_rect, const CEGUI::ColourRect& colours,
              CEGUI::QuadSplitMode quad_split_mode = CEGUI::TopLeftToBottomRight) const
    {
        draw(buffer, CEGUI::Rect(position.d_x, position.d_y,
                          position.d_x + getWidth(),
                          position.d_y + getHeight()),
             clip_rect, colours, quad_split_mode);
    }

    /*!
    \brief
        Queue the image to be drawn.

    \note
        The final position of the Image will be adjusted by the offset values
        defined for this Image object.  If absolute positioning is essential
        then these values should be taken into account prior to calling the
        draw() methods.  However, by doing this you take away the ability of the
        Operatorset designer to adjust the alignment and positioning of Images,
        therefore your component is far less useful since it requires code
        changes to modify image positioning that could have been handled from a
        data file.

    \param buffer
        GeometryBuffer object where the geometry for the image will be queued.

    \param position
        CEGUI::Vector2 object containing the location where the Image is to be drawn

    \param clip_rect
        CEGUI::Rect object that defines an on-screen area that the Image will be
        clipped to when drawing.

    \param top_left_colour
        Colour to be applied to the top-left corner of the Image.

    \param top_right_colour
        Colour to be applied to the top-right corner of the Image.

    \param bottom_left_colour
        Colour to be applied to the bottom-left corner of the Image.

    \param bottom_right_colour
        Colour to be applied to the bottom-right corner of the Image.

    \param quad_split_mode
        One of the CEGUI::QuadSplitMode values specifying the way the quad geometry for
        the image is to be split into triangles.

    \return
        Nothing
    */
    void draw(CEGUI::GeometryBuffer& buffer, const CEGUI::Vector2& position,
              const CEGUI::Rect* clip_rect,
              const CEGUI::colour& top_left_colour = 0xFFFFFFFF,
              const CEGUI::colour& top_right_colour = 0xFFFFFFFF,
              const CEGUI::colour& bottom_left_colour = 0xFFFFFFFF,
              const CEGUI::colour& bottom_right_colour = 0xFFFFFFFF,
              CEGUI::QuadSplitMode quad_split_mode = CEGUI::TopLeftToBottomRight) const
    {
        draw(buffer, CEGUI::Rect(position.d_x, position.d_y,
                          position.d_x + getWidth(),
                          position.d_y + getHeight()),
             clip_rect,
             CEGUI::ColourRect(top_left_colour, top_right_colour,
                        bottom_left_colour, bottom_right_colour),
             quad_split_mode);
    }

    /*!
    \brief
        Queue the image to be drawn.

    \note
        The final position of the Image will be adjusted by the offset values
        defined for this Image object.  If absolute positioning is essential
        then these values should be taken into account prior to calling the
        draw() methods.  However, by doing this you take away the ability of the
        Operatorset designer to adjust the alignment and positioning of Images,
        therefore your component is far less useful since it requires code
        changes to modify image positioning that could have been handled from a
        data file.

    \param buffer
        GeometryBuffer object where the geometry for the image will be queued.

    \param dest_rect
        CEGUI::Rect object defining the area on-screen where the Image is to be drawn.
        The Image will be scaled to fill the area as required.

    \param clip_rect
        CEGUI::Rect object that defines an on-screen area that the Image will be
        clipped to when drawing.

    \param colours
        CEGUI::ColourRect object that describes the colour values to use for each
        corner of the Image.

    \param quad_split_mode
        One of the CEGUI::QuadSplitMode values specifying the way the quad geometry for
        the image is to be split into triangles.

    \return
        Nothing
    */
    void draw(CEGUI::GeometryBuffer& buffer, const CEGUI::Rect& dest_rect,
              const CEGUI::Rect* clip_rect, const CEGUI::ColourRect& colours,
              CEGUI::QuadSplitMode quad_split_mode = CEGUI::TopLeftToBottomRight) const;

    /*!
    \brief
        Writes an xml representation of this Image object to \a out_stream.

    \param xml_stream
        Stream where xml data should be output.


    \return
        Nothing.
    */
    void writeXMLToStream(CEGUI::XMLSerializer& xml_stream) const;


   friend class std::map<CEGUI::String, Operator, CEGUI::String::FastLessCompare>;
   friend struct std::pair<const CEGUI::String, Operator>;


   /*************************************************************************
      Construction and Destruction
   *************************************************************************/
   /*!
   \brief
      Default constructor (only used by std::map)
   */
   Operator(void) {}


   /*!
   \brief
      Constructor for Image objects.  This is not normally used directly by client code, use the Operatorset interface instead.

   \param owner
       CEGUI::Pointer to a Operatorset object that owns this Image.  This must not be NULL.
      
   \param name
       CEGUI::String object describing the name of the image being created.
      
   \param area
      Rect object describing an area that will be associated with this image.
      
   \param render_offset
       CEGUI::Point object that describes the offset to be applied when rendering this image.
      
   \param horzScaling
      float value indicating the initial horizontal scaling to be applied to this image.

   \param vertScaling
      float value indicating the initial vertical scaling to be applied to this image.

   \exception NullObjectException   Thrown if \a owner was NULL.
   */
   Operator(const Operatorset* owner, const CEGUI::String& name, const CEGUI::Rect& area, const CEGUI::Point& render_offset, float horzScaling = 1.0f, float vertScaling = 1.0f);



   /*!
   \brief
      Copy constructor
   */
   Operator(const Operator& image);


   /*!
   \brief
      Destructor for Image objects.
   */
   ~Operator(void);


private:
   /*************************************************************************
      Friends
   *************************************************************************/
   friend class Operatorset;

      
   /*************************************************************************
      Implementation Methods
   *************************************************************************/
   /*!
   \brief
      set the horizontal scaling factor to be applied to this Image

   \param factor
      float value describing the scaling factor required.

   \return
      Nothing.
   */
   void   setHorzScaling(float factor);


   /*!
   \brief
      set the vertical scaling factor to be applied to this Image

   \param factor
      float value describing the scaling factor required.

   \return
      Nothing.
   */
   void   setVertScaling(float factor);


   /*************************************************************************
      Implementation Data
   *************************************************************************/
   const Operatorset*   d_owner;      //!< Link back to Operatorset that owns this image
   Rect         d_area;         //!< CEGUI::Rect defining the area on the texture that makes up this image.
    CEGUI::Point         d_offset;      //!< Offset to use when rendering

   // image auto-scaling fields.
   float   d_scaledWidth;      //!< scaled image width.
   float   d_scaledHeight;      //!< scaled image height.
    CEGUI::Point   d_scaledOffset;      //!< scaled rendering offset.
    CEGUI::String   d_name;            //!< name of this image.
};

} // End of  ProcGen namespace section

#if defined(_MSC_VER)
#   pragma warning(pop)
#endif

#endif   // end of guard _PGOperator_hpp_


PGOperator.cpp

Code: Select all

#include "PGOperator.hpp"
#include "CEGUIExceptions.h"
#include "CEGUITexture.h"
#include "PGOperatorset.hpp"
#include "CEGUIRenderer.h"
#include "CEGUIPropertyHelper.h"
#include <cmath>
#include <iostream>

#ifdef NullObjectException
#undef NullObjectException
#define NullObjectException(message)  \
    NullObjectException(message, __FILE__, __LINE__)
#endif

// Start of ProcGen namespace section
namespace ProcGen
{

/*************************************************************************
   Constructor
*************************************************************************/
Operator::Operator(const Operatorset* owner, const CEGUI::String& name, const CEGUI::Rect& area, const CEGUI::Point& render_offset, float horzScaling, float vertScaling) :
   d_owner(owner),
   d_area(area),
   d_offset(render_offset),
   d_name(name)
{
   if (!d_owner)
   {
      CEGUI_THROW(NullObjectException("Operator::Image - Operatorset pointer passed to Image constructor must be valid."));
   }

   // setup initial image scaling
   setHorzScaling(horzScaling);
   setVertScaling(vertScaling);

   // TODO: if we ever store texture co-ordinates, they should be calculated here.
}

/*************************************************************************
   Copy constructor
*************************************************************************/
Operator::Operator(const Operator& image) :
   d_owner(image.d_owner),
   d_area(image.d_area),
   d_offset(image.d_offset),
   d_scaledWidth(image.d_scaledWidth),
   d_scaledHeight(image.d_scaledHeight),
   d_scaledOffset(image.d_scaledOffset),
   d_name(image.d_name)
{
}

/*************************************************************************
   destructor
*************************************************************************/
Operator::~Operator(void)
{
}


/*************************************************************************
   set the horizontal scaling factor to be applied to this Image
*************************************************************************/
void Operator::setHorzScaling(float factor)
{
   d_scaledWidth      = PixelAligned(d_area.getWidth() * factor);
   d_scaledOffset.d_x   = PixelAligned(d_offset.d_x * factor);
}


/*************************************************************************
   set the vertical scaling factor to be applied to this Image
*************************************************************************/
void Operator::setVertScaling(float factor)
{
   d_scaledHeight      = PixelAligned(d_area.getHeight() * factor);
   d_scaledOffset.d_y   = PixelAligned(d_offset.d_y * factor);
}


/*************************************************************************
    Clip and then queue the image to be rendered.
*************************************************************************/
void Operator::draw(CEGUI::GeometryBuffer& buffer, const CEGUI::Rect& dest_rect,
    const CEGUI::Rect* clip_rect, const CEGUI::ColourRect& colours,
    CEGUI::QuadSplitMode quad_split_mode) const
{
    CEGUI::Rect dest(dest_rect);

    // apply rendering offset to the destination CEGUI::Rect
    dest.offset(d_scaledOffset);

    // draw
    d_owner->draw(buffer, d_area, dest, clip_rect, colours, quad_split_mode);
}


/*************************************************************************
    CEGUI::String object containing the name of this Image   
*************************************************************************/
const CEGUI::String& Operator::getName(void) const
{
   return d_name;
}


/*************************************************************************
   Return the name of the Operatorset that contains this Image   
*************************************************************************/
const CEGUI::String& Operator::getOperatorsetName(void) const
{
   return d_owner->getName();
}

/*************************************************************************
   Return CEGUI::Rect describing the source texture area used by this Image.
*************************************************************************/
const CEGUI::Rect& Operator::getSourceTextureArea(void) const
{
    return d_area;
}


/*************************************************************************
    Output XML <Image ... > element for this image
*************************************************************************/
void Operator::writeXMLToStream(CEGUI::XMLSerializer& xml_stream) const
{
    xml_stream.openTag("Operator")
        .attribute("Name", d_name)
        .attribute("XPos", CEGUI::PropertyHelper::uintToString(static_cast<CEGUI::uint>(d_area.d_left)))
        .attribute("YPos", CEGUI::PropertyHelper::uintToString(static_cast<CEGUI::uint>(d_area.d_top)))
        .attribute("Width", CEGUI::PropertyHelper::uintToString(static_cast<CEGUI::uint>(d_area.getWidth())))
        .attribute("Height", CEGUI::PropertyHelper::uintToString(static_cast<CEGUI::uint>(d_area.getHeight())));

    if (d_offset.d_x != 0.0f)
        xml_stream.attribute("XOffset", CEGUI::PropertyHelper::intToString(static_cast<int>(d_offset.d_x)));

    if (d_offset.d_y != 0.0f)
        xml_stream.attribute("YOffset", CEGUI::PropertyHelper::intToString(static_cast<int>(d_offset.d_x)));

    xml_stream.closeTag();
}


} // End of  ProcGen namespace section


PGOperatorset.hpp

Code: Select all

#ifndef _PGOperatorset_hpp_
#define _PGOperatorset_hpp_

#include "PGOperator.hpp"
#include "PGOperatorsetManager.hpp"
#include "CEGUIBase.h"
#include "CEGUIString.h"
#include "CEGUIRect.h"
#include "CEGUIColourRect.h"
#include "CEGUIIteratorBase.h"
#include "CEGUIXMLSerializer.h"

#include <map>


#if defined(_MSC_VER)
#   pragma warning(push)
#   pragma warning(disable : 4251)
#endif


// Start of ProcGen namespace section
namespace ProcGen
{

/*!
\brief
   Offers functions to define, access, and draw, a set of image components on a single graphical surface or Texture.

   Operatorset objects are a means by which a single graphical image (file, Texture, etc), can be split into a number
   of 'components' which can later be accessed via name.  The components of an Operatorset can queried for
   various details, and sent to the Renderer object for drawing.
*/
class Operatorset
{
   typedef   std::map<CEGUI::String, Operator, CEGUI::String::FastLessCompare>   OperatorRegistry;

public:
   /*!
   \brief
      Construct a new Operatorset object.  Object will initially have no Images defined

   \param texture
      Texture object that holds the imagery for the Operatorset being created.
   */
   Operatorset(const CEGUI::String& name, CEGUI::Texture& texture);

   /*!
   \brief
        Construct a new Operatorset using the specified image file and operatorset name.  The created
        operatorset will, by default, have a single Image defined named "full_image" which represents
        the entire area of the loaded image file.

    \note
        Under certain renderers it may be required that the source image dimensions be some
        power of 2, if this condition is not met then stretching and other undesired side-effects
        may be experienced.  To be safe from such effects it is generally recommended that all
        images that you load have dimensions that are some power of 2.

    \param name
        CEGUI::String object holding the name to be assigned to the created operatorset.

    \param filename
        CEGUI::String object holding the filename of the image that is to be loaded.  The image should be
        of some format that is supported by the Renderer that is in use.

    \param resourceGroup
        Resource group identifier to be passed to the resource manager, which may specify a group
        from which the image file is to be loaded.

    \exception FileIOException thrown if something goes wrong while loading the image.
    */
    Operatorset(const CEGUI::String& name, const CEGUI::String& filename, const CEGUI::String& resourceGroup);

   /*!
   \brief
      Destroys Operatorset objects
   */
   ~Operatorset(void);


   typedef   CEGUI::ConstBaseIterator<OperatorRegistry>   ImageIterator;   //!< Iterator type for this collection

   /*************************************************************************
      Public interface
   *************************************************************************/
   /*!
   \brief
      return Texture object for this Operatorset

   \return
      Texture object that holds the imagery for this Operatorset
   */
   CEGUI::Texture*   getTexture(void) const                  {return d_texture;}


   /*!
   \brief
      return CEGUI::String object holding the name of the Operatorset

   \return   
       CEGUI::String object that holds the name of the Operatorset.
   */
   const CEGUI::String&   getName(void) const                  {return d_name;}


   /*!
   \brief
      return number of images defined for this Operatorset

   \return
      CEGUI::uint value equal to the number of Image objects defined for the Operatorset
   */
   CEGUI::uint      getImageCount(void) const               {return (CEGUI::uint)d_images.size();}

 
   /*!
   \brief
      return true if an Image with the specified name exists.

   \param name
       CEGUI::String object holding the name of the Image to look for.

   \return
      true if an Image object named \a name is defined for this Operatorset, else false.
   */
   bool      isImageDefined(const CEGUI::String& name) const   {return d_images.find(name) != d_images.end();}

 
   /*!
   \brief
      return a copy of the Image object for the named image

   \param name
       CEGUI::String object holding the name of the Image object to be returned

   \return
      constant Image object that has the requested name.

   \exception UnknownObjectException   thrown if no Image named \a name is defined for the Operatorset
   */
   const Operator&   getOperator(const CEGUI::String& name) const;


   /*!
   \brief
      remove the definition for the Image with the specified name.  If no such Image exists, nothing happens.

   \param name
       CEGUI::String object holding the name of the Image object to be removed from the Operatorset,
   \return
      Nothing.
   */
   void   undefineOperator(const CEGUI::String& name);

   /*!
   \brief
      Removes the definitions for all Image objects currently defined in the Operatorset

   \return
      Nothing
   */
   void   undefineAllImages(void);


   /*!
   \brief
      return a CEGUI::Size object describing the dimensions of the named image.

   \param name
       CEGUI::String object holding the name of the Image.

   \return
       CEGUI::Size object holding the dimensions of the requested Image.

   \exception UnknownObjectException   thrown if no Image named \a name is defined for the Operatorset
   */
    CEGUI::Size   getOperatorSize(const CEGUI::String& name) const         {return getOperator(name).getSize();}


   /*!
   \brief
      return the width of the named image.

   \param name
       CEGUI::String object holding the name of the Image.

   \return
      float value equalling the width of the requested Image.

   \exception UnknownObjectException   thrown if no Image named \a name is defined for the Operatorset
   */
   float   getImageWidth(const CEGUI::String& name) const         {return getOperator(name).getWidth();}


   /*!
   \brief
      return the height of the named image.

   \param name
       CEGUI::String object holding the name of the Image.

   \return
      float value equalling the height of the requested Image.

   \exception UnknownObjectException   thrown if no Image named \a name is defined for the Operatorset
   */
   float   getImageHeight(const CEGUI::String& name) const      {return getOperator(name).getHeight();}


   /*!
   \brief
      return the rendering offsets applied to the named image.

   \param name
       CEGUI::String object holding the name of the Image.

   \return
       CEGUI::Point object that holds the rendering offsets for the requested Image.

   \exception UnknownObjectException   thrown if no Image named \a name is defined for the Operatorset
   */
    CEGUI::Point   getImageOffset(const CEGUI::String& name) const      {return getOperator(name).getOffsets();}


   /*!
   \brief
      return the x rendering offset for the named image.

   \param name
       CEGUI::String object holding the name of the Image.

   \return
      float value equal to the x rendering offset applied when drawing the requested Image.

   \exception UnknownObjectException   thrown if no Image named \a name is defined for the Operatorset
   */
   float   getImageOffsetX(const CEGUI::String& name) const      {return getOperator(name).getOffsetX();}


   /*!
   \brief
      return the y rendering offset for the named image.

   \param name
       CEGUI::String object holding the name of the Image.

   \return
      float value equal to the y rendering offset applied when drawing the requested Image.

   \exception UnknownObjectException   thrown if no Image named \a name is defined for the Operatorset
   */
   float   getImageOffsetY(const CEGUI::String& name) const      {return getOperator(name).getOffsetY();}

   
   /*!
   \brief
      Define a new Image for this Operatorset

   \param name
       CEGUI::String object holding the name that will be assigned to the new Operator, which must be unique within the Operatorset.

   \param position
       CEGUI::Point object describing the pixel location of the Image on the image file / texture associated with this Operatorset.

   \param size
       CEGUI::Size object describing the dimensions of the Operator, in pixels.

   \param render_offset
       CEGUI::Point object describing the offsets, in pixels, that are to be applied to the Image when it is drawn.

   \return
      Nothing

   \exception AlreadyExistsException   thrown if an Image named \a name is already defined for this Operatorset
   */
   void   defineOperator(const CEGUI::String& name, const CEGUI::Point& position, const CEGUI::Size& size, const CEGUI::Point& render_offset)
   {
      defineOperator(name, CEGUI::Rect(position.d_x, position.d_y, position.d_x + size.d_width, position.d_y + size.d_height), render_offset);
   }


   /*!
   \brief
      Define a new Image for this Operatorset

   \param name
       CEGUI::String object holding the name that will be assigned to the new Operator, which must be unique within the Operatorset.

   \param image_rect
      Rect object describing the area on the image file / texture associated with this Operatorset that will be used for the Image.

   \param render_offset
       CEGUI::Point object describing the offsets, in pixels, that are to be applied to the Image when it is drawn.

   \return
      Nothing

   \exception AlreadyExistsException   thrown if an Image named \a name is already defined for this Operatorset
   */
   void   defineOperator(const CEGUI::String& name, const CEGUI::Rect& image_rect, const CEGUI::Point& render_offset);


    /*!
    \brief
        Queues an area of the associated Texture the be drawn on the screen.
        Low-level routine to be used carefully!

    \param buffer
        GeometryBuffer object where the geometry for the area to be drawn will
        be queued.

    \param source_rect
        CEGUI::Rect object describing the area of the image file / texture that is to
        be queued for drawing

    \param dest_rect
        CEGUI::Rect describing the area of the screen that will be filled with the
        imagery from \a source_rect.

    \param clip_rect
        CEGUI::Rect object describing a 'clipping rectangle' that will be applied when
        drawing the requested imagery

    \param colours
        CEGUI::ColourRect object holding the ARGB colours to be applied to the four
        corners of the rendered imagery.

    \param quad_split_mode
        One of the CEGUI::QuadSplitMode values specifying the way the quad geometry for
        the image is to be split into triangles.

    \return
        Nothing
    */
    void draw(CEGUI::GeometryBuffer& buffer, const CEGUI::Rect& source_rect,
              const CEGUI::Rect& dest_rect, const CEGUI::Rect* clip_rect,
              const CEGUI::ColourRect& colours, CEGUI::QuadSplitMode quad_split_mode) const;

    /*!
    \brief
        Queues an area of the associated Texture the be drawn on the screen.
        Low-level routine to be used carefully!

    \param buffer
        GeometryBuffer object where the geometry for the area to be drawn will
        be queued.

    \param source_rect
        CEGUI::Rect object describing the area of the image file / texture that is to
        be queued for drawing.

    \param dest_rect
        CEGUI::Rect describing the area of the screen that will be filled with the
        imagery from \a source_rect.

    \param clip_rect
        CEGUI::Rect object describing a 'clipping rectangle' that will be applied when
        drawing the requested imagery.

    \param top_left_colour
        colour to be applied to the top left corner of the rendered imagery.

    \param top_right_colour
        colour to be applied to the top right corner of the rendered imagery.

    \param bottom_left_colour
        colour to be applied to the bottom left corner of the rendered imagery.

    \param bottom_right_colour
        colour to be applied to the bottom right corner of the rendered imagery.

    \param quad_split_mode
        One of the CEGUI::QuadSplitMode values specifying the way the quad geometry for
        the image is to be split into triangles.

    \return
        Nothing
    */
    void draw(CEGUI::GeometryBuffer& buffer, const CEGUI::Rect& source_rect,
              const CEGUI::Rect& dest_rect, const CEGUI::Rect* clip_rect,
              const CEGUI::colour& top_left_colour = 0xFFFFFFFF,
              const CEGUI::colour& top_right_colour = 0xFFFFFFFF,
              const CEGUI::colour& bottom_left_colour = 0xFFFFFFFF,
              const CEGUI::colour& bottom_right_colour = 0xFFFFFFFF,
              CEGUI::QuadSplitMode quad_split_mode = CEGUI::TopLeftToBottomRight) const
    {
        draw(buffer, source_rect, dest_rect, clip_rect,
             CEGUI::ColourRect(top_left_colour, top_right_colour,
                        bottom_left_colour, bottom_right_colour),
             quad_split_mode);
    }

   /*!
   \brief
      Return whether this Operatorset is auto-scaled.

   \return
      true if Operatorset is auto-scaled, false if not.
   */
   bool   isAutoScaled(void) const      {return d_autoScale;}


   /*!
   \brief
      Return the native display size for this Operatorset.  This is only relevant if the Operatorset is being auto-scaled.

   \return
       CEGUI::Size object describing the native display size for this Operatorset.
   */
    CEGUI::Size   getNativeResolution(void) const   {return CEGUI::Size(d_nativeHorzRes, d_nativeVertRes);}


   /*!
   \brief
      Enable or disable auto-scaling for this Operatorset.

   \param setting
      true to enable auto-scaling, false to disable auto-scaling.

   \return
      Nothing.
   */
   void   setAutoScalingEnabled(bool setting);


   /*!
   \brief
      Set the native resolution for this Operatorset

   \param size
       CEGUI::Size object describing the new native screen resolution for this Operatorset.

   \return
      Nothing
   */
   void   setNativeResolution(const CEGUI::Size& size);


    /*!
    \brief
        Notify the Operatorset that the display size may have changed.

    \param size
        CEGUI::Size object describing the display resolution
    */
    void notifyDisplaySizeChanged(const CEGUI::Size& size);


   /*!
   \brief
      Return an Operatorset::ImageIterator object that can be used to iterate over the Image objects in the Operatorset.
   */
   ImageIterator   getIterator(void) const;


    /*!
    \brief
        Writes an xml representation of this Operatorset to \a out_stream.

    \param out_stream
        Stream where xml data should be output.

    \param indentLevel
        Current XML indentation level

    \return
        Nothing.
    */
    void writeXMLToStream(CEGUI::XMLSerializer& xml_stream) const;

    /*!
    \brief
        Sets the default resource group to be used when loading operatorset data

    \param resourceGroup
        CEGUI::String describing the default resource group identifier to be used.

    \return
        Nothing.
    */
    static void setDefaultResourceGroup(const CEGUI::String& resourceGroup)
        { d_defaultResourceGroup = resourceGroup; }

    /*!
    \brief
        Returns the default resource group currently set for Operatorsets.

    \return
        CEGUI::String describing the default resource group identifier that will be
        used when loading Operatorset data.
    */
    static const CEGUI::String& getDefaultResourceGroup()
        { return d_defaultResourceGroup; }

protected:
   /*************************************************************************
      Implementation Functions
   *************************************************************************/
   /*!
   \brief
      Unloads all loaded data and leaves the Operatorset in a clean (but un-usable) state.  This should be called for cleanup purposes only.
   */
   void   unload(void);


   /*!
   \brief
      set the Texture object to be used by this Operatorset.  Changing textures on an Operatorset that is in use is not a good idea!

   \param texture
      Texture object to be used by the Operatorset.  The old texture is NOT disposed of, that is the clients responsibility.

   \return
      Nothing

   \exception   NullObjectException      thrown if \a texture is NULL
   */
   void   setTexture(CEGUI::Texture* texture);


   /*!
   \brief
      Sets the scaling factor for all Images that are a part of this Operatorset.

   \return
      Nothing.
   */
   void   updateImageScalingFactors(void);

   /*************************************************************************
      Implementation Data
   *************************************************************************/
    CEGUI::String         d_name;                  //!< Holds the name of this operatorset.
   OperatorRegistry   d_images;               //!< Registry of Image objects for the images defined for this Operatorset
   CEGUI::Texture*      d_texture;               //!< Texture object that handles imagery for this Operatorset
    CEGUI::String          d_textureFilename;          //!< CEGUI::String holding the name of the texture filename (if any).

   // auto-scaling fields
   bool   d_autoScale;         //!< true when auto-scaling is enabled.
   float   d_horzScaling;         //!< current horizontal scaling factor.
   float   d_vertScaling;         //!< current vertical scaling factor.
   float   d_nativeHorzRes;      //!< native horizontal resolution for this Operatorset.
   float   d_nativeVertRes;      //!< native vertical resolution for this Operatorset.
    static CEGUI::String d_defaultResourceGroup;   //!< Default resource group specifically for Operatorsets.
};

} // End of  ProcGen namespace section

#if defined(_MSC_VER)
#   pragma warning(pop)
#endif

#endif   // end of guard _PGOperatorset_hpp_


PGOperatorset.cpp

Code: Select all

#include "PGOperatorset.hpp"
#include "CEGUIExceptions.h"
#include "CEGUITexture.h"
#include "CEGUIRenderer.h"
#include "CEGUISystem.h"
#include "PGOperatorset_xmlHandler.hpp"
#include "CEGUILogger.h"
#include "CEGUIDataContainer.h"
#include "CEGUIXMLParser.h"
#include "CEGUIXMLSerializer.h"
#include "CEGUIPropertyHelper.h"
#include "CEGUIGeometryBuffer.h"
#include "CEGUIVertex.h"
#include <iostream>
#include <cmath>

#ifdef NullObjectException
#undef NullObjectException
#define NullObjectException(message)  \
    CEGUI::NullObjectException(message, __FILE__, __LINE__)
#endif

#ifdef UnknownObjectException
#undef UnknownObjectException
#define UnknownObjectException(message)  \
    CEGUI::UnknownObjectException(message, __FILE__, __LINE__)
#endif

#ifdef AlreadyExistsException
#undef AlreadyExistsException
#define AlreadyExistsException(message)  \
    CEGUI::AlreadyExistsException(message, __FILE__, __LINE__)
#endif

// Start of ProcGen namespace section
namespace ProcGen
{

/*************************************************************************
   Definition of static /const data for Operatorset (and sub-classes)
*************************************************************************/
// Declared in Operatorset
String Operatorset::d_defaultResourceGroup;


/*************************************************************************
   constructor
*************************************************************************/
Operatorset::Operatorset(const CEGUI::String& name, CEGUI::Texture& texture) :
   d_name(name),
   d_texture(&texture)
{
   if (!d_texture)
   {
      CEGUI_THROW(NullObjectException("Operatorset::Operatorset - Texture object supplied for Operatorset creation must be valid."));
   }
   // defaults for scaling options
   d_autoScale = false;
   setNativeResolution(CEGUI::Size(CEGUI::DefaultNativeHorzRes, CEGUI::DefaultNativeVertRes));
}


Operatorset::Operatorset(const CEGUI::String& name, const CEGUI::String& filename, const CEGUI::String& resourceGroup) :
    d_name(name)
{
    // try to load the image file using the renderer
    d_texture =
        &CEGUI::System::getSingleton().getRenderer()->createTexture(filename,
        resourceGroup.empty() ? d_defaultResourceGroup : resourceGroup);

    // store texture filename
    d_textureFilename = filename;
    // TODO: Should we store the resource group too?

    // initialse the auto-scaling for this Operatorset
    d_autoScale = true;
    setNativeResolution(d_texture->getSize());

    // define the default image for this Operatorset
    defineOperator(
        "full_image",
        CEGUI::Rect(0, 0,
             d_texture->getOriginalDataSize().d_width,
             d_texture->getOriginalDataSize().d_height),
        CEGUI::Point(0, 0)
    );
}


/*************************************************************************
   destructor
*************************************************************************/
Operatorset::~Operatorset(void)
{
   unload();
}


/*************************************************************************
   Set texture for use by this operatorset object
*************************************************************************/
void Operatorset::setTexture(CEGUI::Texture* texture)
{
   if (!d_texture)
   {
      CEGUI_THROW(NullObjectException("Operatorset::setTexture - Texture object supplied for Operatorset creation must be valid."));
   }

   d_texture = texture;
}


/*************************************************************************
   return the Image object for the named image
*************************************************************************/
const Operator& Operatorset::getOperator(const CEGUI::String& name) const
{
   OperatorRegistry::const_iterator   pos = d_images.find(name);

   if (pos == d_images.end())
   {
      CEGUI_THROW(UnknownObjectException("Operatorset::getImage - The Image named '" + name + "' could not be found in Operatorset '" + d_name + "'."));
   }

   return pos->second;
}


/*************************************************************************
   defines a new Image.
*************************************************************************/
void Operatorset::defineOperator(const CEGUI::String& name, const CEGUI::Rect& image_rect, const CEGUI::Point& render_offset)
{
   if (isImageDefined(name))
   {
      CEGUI_THROW(AlreadyExistsException("Operatorset::defineImage - An image with the name '" + name + "' already exists in Operatorset '" + d_name + "'."));
   }

   // get scaling factors
   float hscale = d_autoScale ? d_horzScaling : 1.0f;
   float vscale = d_autoScale ? d_vertScaling : 1.0f;

   // add the Image definition
   d_images[name] = Operator(this, name, image_rect, render_offset, hscale, vscale);

   CEGUI_LOGINSANE("Operator '" + name + "' has been defined for Operatorset '" + d_name + "'.")
}


/*************************************************************************
    Queues an area of the associated Texture the be drawn on the screen.
    Low-level routine not normally used!
*************************************************************************/
void Operatorset::draw(CEGUI::GeometryBuffer& buffer, const CEGUI::Rect& source_rect,
    const CEGUI::Rect& dest_rect, const CEGUI::Rect* clip_rect,const CEGUI::ColourRect& colours,
    CEGUI::QuadSplitMode quad_split_mode) const
{
    // get the rect area that we will actually draw to (i.e. perform clipping)
    CEGUI::Rect final_rect(clip_rect ? dest_rect.getIntersection(*clip_rect) : dest_rect );

    // check if rect was totally clipped
    if ((final_rect.getWidth() == 0) || (final_rect.getHeight() == 0))
        return;

    // Fix bug #45
    // Obtain correct scale values from the texture
    const float x_scale = d_texture->getTexelScaling().d_x;
    const float y_scale = d_texture->getTexelScaling().d_y;

    float tex_per_pix_x = source_rect.getWidth() / dest_rect.getWidth();
    float tex_per_pix_y = source_rect.getHeight() / dest_rect.getHeight();

    // calculate final, clipped, texture co-ordinates
    CEGUI::Rect  tex_rect((source_rect.d_left + ((final_rect.d_left - dest_rect.d_left) * tex_per_pix_x)) * x_scale,
        (source_rect.d_top + ((final_rect.d_top - dest_rect.d_top) * tex_per_pix_y)) * y_scale,
        (source_rect.d_right + ((final_rect.d_right - dest_rect.d_right) * tex_per_pix_x)) * x_scale,
        (source_rect.d_bottom + ((final_rect.d_bottom - dest_rect.d_bottom) * tex_per_pix_y)) * y_scale);

    final_rect.d_left   = PixelAligned(final_rect.d_left);
    final_rect.d_right   = PixelAligned(final_rect.d_right);
    final_rect.d_top   = PixelAligned(final_rect.d_top);
    final_rect.d_bottom   = PixelAligned(final_rect.d_bottom);

    CEGUI::Vertex vbuffer[6];

    // vertex 0
    vbuffer[0].position   = CEGUI::Vector3(final_rect.d_left, final_rect.d_top, 0.0f);
    vbuffer[0].colour_val = colours.d_top_left;
    vbuffer[0].tex_coords = CEGUI::Vector2(tex_rect.d_left, tex_rect.d_top);

    // vertex 1
    vbuffer[1].position   = CEGUI::Vector3(final_rect.d_left, final_rect.d_bottom, 0.0f);
    vbuffer[1].colour_val = colours.d_bottom_left;
    vbuffer[1].tex_coords = CEGUI::Vector2(tex_rect.d_left, tex_rect.d_bottom);

    // vertex 2
    vbuffer[2].position.d_x   = final_rect.d_right;
    vbuffer[2].position.d_z   = 0.0f;
    vbuffer[2].colour_val     = colours.d_bottom_right;
    vbuffer[2].tex_coords.d_x = tex_rect.d_right;

    // top-left to bottom-right diagonal
    if (quad_split_mode == CEGUI::TopLeftToBottomRight)
    {
        vbuffer[2].position.d_y   = final_rect.d_bottom;
        vbuffer[2].tex_coords.d_y = tex_rect.d_bottom;
    }
    // bottom-left to top-right diagonal
    else
    {
        vbuffer[2].position.d_y   = final_rect.d_top;
        vbuffer[2].tex_coords.d_y = tex_rect.d_top;
    }

    // vertex 3
    vbuffer[3].position   = CEGUI::Vector3(final_rect.d_right, final_rect.d_top, 0.0f);
    vbuffer[3].colour_val = colours.d_top_right;
    vbuffer[3].tex_coords = CEGUI::Vector2(tex_rect.d_right, tex_rect.d_top);

    // vertex 4
    vbuffer[4].position.d_x   = final_rect.d_left;
    vbuffer[4].position.d_z   = 0.0f;
    vbuffer[4].colour_val     = colours.d_top_left;
    vbuffer[4].tex_coords.d_x = tex_rect.d_left;

    // top-left to bottom-right diagonal
    if (quad_split_mode == CEGUI::TopLeftToBottomRight)
    {
        vbuffer[4].position.d_y   = final_rect.d_top;
        vbuffer[4].tex_coords.d_y = tex_rect.d_top;
    }
    // bottom-left to top-right diagonal
    else
    {
        vbuffer[4].position.d_y   = final_rect.d_bottom;
        vbuffer[4].tex_coords.d_y = tex_rect.d_bottom;
    }

    // vertex 5
    vbuffer[5].position = CEGUI::Vector3(final_rect.d_right, final_rect.d_bottom, 0.0f);
    vbuffer[5].colour_val= colours.d_bottom_right;
    vbuffer[5].tex_coords = CEGUI::Vector2(tex_rect.d_right, tex_rect.d_bottom);

    // TODO: Remove cast when GeometryBuffer gets it's APIs fixed!
    buffer.setActiveTexture((CEGUI::Texture*)d_texture);
    buffer.appendGeometry(vbuffer, 6);
}

/*************************************************************************
   Unload all data, leaving Operatorset in a clean (but unusable) state
*************************************************************************/
void Operatorset::unload(void)
{
   undefineAllImages();

   // cleanup texture
   CEGUI::System::getSingleton().getRenderer()->destroyTexture(*d_texture);
   d_texture = 0;
}


/*************************************************************************
   Sets the scaling factor for all Images that are a part of this Operatorset.
*************************************************************************/
void Operatorset::updateImageScalingFactors(void)
{
   float hscale, vscale;

   if (d_autoScale)
   {
      hscale = d_horzScaling;
      vscale = d_vertScaling;
   }
   else
   {
      hscale = vscale = 1.0f;
   }

   OperatorRegistry::iterator pos = d_images.begin(), end = d_images.end();
   for(; pos != end; ++pos)
   {
      pos->second.setHorzScaling(hscale);
      pos->second.setVertScaling(vscale);
   }

}


/*************************************************************************
   Enable or disable auto-scaling for this Operatorset.
*************************************************************************/
void Operatorset::setAutoScalingEnabled(bool setting)
{
   if (setting != d_autoScale)
   {
      d_autoScale = setting;
      updateImageScalingFactors();
   }

}


/*************************************************************************
   Set the native resolution for this Operatorset
*************************************************************************/
void Operatorset::setNativeResolution(const CEGUI::Size& size)
{
   d_nativeHorzRes = size.d_width;
   d_nativeVertRes = size.d_height;

   // re-calculate scaling factors & notify images as required
   notifyDisplaySizeChanged(
       CEGUI::System::getSingleton().getRenderer()->getDisplaySize());
}


/*************************************************************************
   Notify the Operatorset of the current (usually new) display resolution.
*************************************************************************/
void Operatorset::notifyDisplaySizeChanged(const CEGUI::Size& size)
{
   d_horzScaling = size.d_width / d_nativeHorzRes;
   d_vertScaling = size.d_height / d_nativeVertRes;

   if (d_autoScale)
   {
      updateImageScalingFactors();
   }

}

void Operatorset::writeXMLToStream(CEGUI::XMLSerializer& xml_stream) const
{
    // output Operatorset tag
    xml_stream.openTag("Operators")
        .attribute("Name", d_name)
        .attribute("Imagefile", d_textureFilename);

    if (d_nativeHorzRes != CEGUI::DefaultNativeHorzRes)
        xml_stream.attribute("NativeHorzRes",
          CEGUI::PropertyHelper::uintToString(static_cast<CEGUI::uint>(d_nativeHorzRes)));
    if (d_nativeVertRes != CEGUI::DefaultNativeVertRes)
        xml_stream.attribute("NativeVertRes",
          CEGUI::PropertyHelper::uintToString(static_cast<CEGUI::uint>(d_nativeVertRes)));

    if (d_autoScale)
        xml_stream.attribute("AutoScaled", "true");

    // output images
    ImageIterator image = getIterator();
    while (!image.isAtEnd())
    {
        image.getCurrentValue().writeXMLToStream(xml_stream);
        ++image;
    }

    // output closing tag
    xml_stream.closeTag();
}


/*************************************************************************
   Return an iterator object that can be used to iterate over the Image
   objects in the Operatorset.
*************************************************************************/
Operatorset::ImageIterator Operatorset::getIterator(void) const
{
   return ImageIterator(d_images.begin(), d_images.end());
}


void Operatorset::undefineOperator(const CEGUI::String& name)
{
   d_images.erase(name);

   CEGUI_LOGINSANE("Operator '" + name + "' has been removed from Operatorset '" + d_name + "'.")
}


void Operatorset::undefineAllImages(void)
{
   d_images.clear();

   CEGUI_LOGINSANE("All images have been removed from Operatorset '" + d_name + "'.")
}

} // End of  ProcGen namespace section


PGOperatorset_xmlHandler.hpp

Code: Select all

#ifndef _PGOperatorset_xmlHandler_hpp_
#define _PGOperatorset_xmlHandler_hpp_

#include "CEGUIXMLHandler.h"
#include "CEGUIString.h"
#include "PGOperator.hpp"
#include "PGOperatorset.hpp"

// Start of ProcGen namespace section
namespace ProcGen
{
//! Class used to parse the Operatorset XML files to create Operatorset objects
class Operatorset_xmlHandler : public CEGUI::XMLHandler
{
public:
    //! Constructor.
    Operatorset_xmlHandler(const CEGUI::String& filename, const CEGUI::String& resource_group);

    //! Destructor.
    ~Operatorset_xmlHandler();

    //! Return string holding the name of the created Operatorset.
    const CEGUI::String& getObjectName() const;

    //! Return reference to the created Operatorset object.
    Operatorset& getObject() const;

    // CEGUI::XMLHandler overrides
    void elementStart(const CEGUI::String& element, const CEGUI::XMLAttributes& attributes);
    void elementEnd(const CEGUI::String& element);

private:
    //! Method that handles the opening Operatorset XML element.
    void elementOperatorsetStart(const CEGUI::XMLAttributes& attributes);
    //! Method that handles the Image XML element.
    void elementImageStart(const CEGUI::XMLAttributes& attributes);
    //! Method that handles the closing Operatorset XML element.
    void elementOperatorsetEnd();

    //! Filename of the XML schema used for validating Operatorset files.
    static const CEGUI::String OperatorsetSchemaName;
    //! Tag name for Operatorset elements.
    static const CEGUI::String OperatorsetElement;
    //! Tag name for Image elements.
    static const CEGUI::String ImageElement;
    //! Attribute name that stores the name of the Operatorset
    static const CEGUI::String OperatorsetNameAttribute;
    //! Attribute name that stores the filename for the image file.
    static const CEGUI::String OperatorsetImageFileAttribute;
    //! Attribute name that stores resource group used when loading image file.
    static const CEGUI::String OperatorsetResourceGroupAttribute;
    //! Attribute that stores 'native' horizontal resolution for the Operatorset.
    static const CEGUI::String OperatorsetNativeHorzResAttribute;
    //! Attribute that stores 'native' vertical resolution for the Operatorset.
    static const CEGUI::String OperatorsetNativeVertResAttribute;
    //! Attribute that specifies whether the Operatorset should be auto-scaled.
    static const CEGUI::String OperatorsetAutoScaledAttribute;
    //! Attribute name that stores the name of the new Image.
    static const CEGUI::String ImageNameAttribute;
    //! Attribute name that stores the x position of the new Image.
    static const CEGUI::String ImageXPosAttribute;
    //! Attribute name that stores the y position of the new Image.
    static const CEGUI::String ImageYPosAttribute;
    //! Attribute name that stores the width of the new Image.
    static const CEGUI::String ImageWidthAttribute;
    //! Attribute name that stores the height of the new Image.
    static const CEGUI::String ImageHeightAttribute;
    //! Attribute name that stores the x rendering offset of the new Image.
    static const CEGUI::String ImageXOffsetAttribute;
    //!< Attribute name that stores the y rendering offset of the new Image.
    static const CEGUI::String ImageYOffsetAttribute;

    //! CEGUI::Pointer to the Operatorset created.
    Operatorset* d_operatorset;
    //! inidcates whether client read the created object
    mutable bool d_objectRead;
};

} // End of  ProcGen namespace section

#endif  // end of guard _PGOperatorset_xmlHandler_hpp_


PGOperatorset_xmlHandler.cpp

Code: Select all

#include "PGOperatorset_xmlHandler.hpp"
#include "CEGUIExceptions.h"
#include "CEGUISystem.h"
#include "CEGUILogger.h"
#include "CEGUIXMLAttributes.h"
#include "CEGUIXMLParser.h"
#include "PGOperatorset.hpp"

#ifdef InvalidRequestException
#undef InvalidRequestException
#define InvalidRequestException(message)  \
    CEGUI::InvalidRequestException(message, __FILE__, __LINE__)
#endif

// Start of ProcGen namespace section
namespace ProcGen
{
//----------------------------------------------------------------------------//
const CEGUI::String Operatorset_xmlHandler::OperatorsetSchemaName("Operatorset.xsd");
const CEGUI::String Operatorset_xmlHandler::OperatorsetElement( "Operators" );
const CEGUI::String Operatorset_xmlHandler::ImageElement( "Operator" );
const CEGUI::String Operatorset_xmlHandler::OperatorsetImageFileAttribute( "Imagefile" );
const CEGUI::String Operatorset_xmlHandler::OperatorsetResourceGroupAttribute( "ResourceGroup" );
const CEGUI::String Operatorset_xmlHandler::OperatorsetNameAttribute( "Name" );
const CEGUI::String Operatorset_xmlHandler::OperatorsetNativeHorzResAttribute( "NativeHorzRes" );
const CEGUI::String Operatorset_xmlHandler::OperatorsetNativeVertResAttribute( "NativeVertRes" );
const CEGUI::String Operatorset_xmlHandler::OperatorsetAutoScaledAttribute( "AutoScaled" );
const CEGUI::String Operatorset_xmlHandler::ImageNameAttribute( "Name" );
const CEGUI::String Operatorset_xmlHandler::ImageXPosAttribute( "XPos" );
const CEGUI::String Operatorset_xmlHandler::ImageYPosAttribute( "YPos" );
const CEGUI::String Operatorset_xmlHandler::ImageWidthAttribute( "Width" );
const CEGUI::String Operatorset_xmlHandler::ImageHeightAttribute( "Height" );
const CEGUI::String Operatorset_xmlHandler::ImageXOffsetAttribute( "XOffset" );
const CEGUI::String Operatorset_xmlHandler::ImageYOffsetAttribute( "YOffset" );

//----------------------------------------------------------------------------//
Operatorset_xmlHandler::Operatorset_xmlHandler(const CEGUI::String& filename,
                                         const CEGUI::String& resource_group) :
    d_operatorset(0),
    d_objectRead(false)
{
    CEGUI::System::getSingleton().getXMLParser()->parseXMLFile(
            *this, filename, OperatorsetSchemaName,
            resource_group.empty() ? Operatorset::getDefaultResourceGroup() :
                                     resource_group);
}

//----------------------------------------------------------------------------//
Operatorset_xmlHandler::~Operatorset_xmlHandler()
{
    if (!d_objectRead)
        delete d_operatorset;
}

//----------------------------------------------------------------------------//
const CEGUI::String& Operatorset_xmlHandler::getObjectName() const
{
    if (!d_operatorset)
        CEGUI_THROW(InvalidRequestException("Operatorset_xmlHandler::getName: "
            "Attempt to access null object."));

    return d_operatorset->getName();
}

//----------------------------------------------------------------------------//
Operatorset& Operatorset_xmlHandler::getObject() const
{
    if (!d_operatorset)
        CEGUI_THROW(InvalidRequestException("Operatorset_xmlHandler::getObject: "
            "Attempt to access null object."));

    d_objectRead = true;
    return *d_operatorset;
}

//----------------------------------------------------------------------------//
void Operatorset_xmlHandler::elementStart(const CEGUI::String& element,
                                       const CEGUI::XMLAttributes& attributes)
{
    // handle an Image element
    if (element == ImageElement)
        elementImageStart(attributes);
    // handle root Operatorset element
    else if (element == OperatorsetElement)
        elementOperatorsetStart(attributes);
    // anything else is a non-fatal error.
    else
        CEGUI::Logger::getSingleton().logEvent("Operatorset_xmlHandler::elementStart: "
            "Unknown element encountered: <" + element + ">", CEGUI::Errors);
}

//----------------------------------------------------------------------------//
void Operatorset_xmlHandler::elementEnd(const CEGUI::String& element)
{
    if (element == OperatorsetElement)
        elementOperatorsetEnd();
}

//----------------------------------------------------------------------------//
void Operatorset_xmlHandler::elementOperatorsetStart(const CEGUI::XMLAttributes& attributes)
{
    // get name of the operatorset.
    const CEGUI::String name(attributes.getValueAsString(OperatorsetNameAttribute));
    // get texture image filename
    const CEGUI::String filename(
        attributes.getValueAsString(OperatorsetImageFileAttribute));
    // get resource group to use for image file.
    const CEGUI::String resource_group(
        attributes.getValueAsString(OperatorsetResourceGroupAttribute));

    CEGUI::Logger& logger(CEGUI::Logger::getSingleton());
    logger.logEvent("Started creation of Operatorset from XML specification:");
    logger.logEvent("---- CEGUI Operatorset name: " + name);
    logger.logEvent("---- Source texture file: " + filename +
                    " in resource group: " +
                    (resource_group.empty() ? "(Default)" : resource_group));

    // Create operatorset object from image file
    d_operatorset = new Operatorset(name, filename, resource_group);

    // set native resolution for operatorset
    const float native_hres = static_cast<float>(
        attributes.getValueAsInteger(OperatorsetNativeHorzResAttribute, 640));
    const float native_vres = static_cast<float>(
        attributes.getValueAsInteger(OperatorsetNativeVertResAttribute, 480));
    d_operatorset->setNativeResolution(CEGUI::Size(native_hres, native_vres));

    // set auto-scaling as needed
    d_operatorset->setAutoScalingEnabled(
        attributes.getValueAsBool(OperatorsetAutoScaledAttribute, false));
}

//----------------------------------------------------------------------------//
void Operatorset_xmlHandler::elementImageStart(const CEGUI::XMLAttributes& attributes)
{
    if (!d_operatorset)
        CEGUI_THROW(InvalidRequestException(
            "Operatorset_xmlHandler::elementImageStart: "
            "Attempt to access null object."));

    const CEGUI::String name(attributes.getValueAsString(ImageNameAttribute));

    CEGUI::Rect    rect;
    rect.d_left =
        static_cast<float>(attributes.getValueAsInteger(ImageXPosAttribute));
    rect.d_top  =
        static_cast<float>(attributes.getValueAsInteger(ImageYPosAttribute));
    rect.setWidth(
        static_cast<float>(attributes.getValueAsInteger(ImageWidthAttribute)));
    rect.setHeight(
        static_cast<float>(attributes.getValueAsInteger(ImageHeightAttribute)));

    const CEGUI::Point offset(
        static_cast<float>(attributes.getValueAsInteger(ImageXOffsetAttribute, 0)),
        static_cast<float>(attributes.getValueAsInteger(ImageYOffsetAttribute, 0)));

    d_operatorset->defineOperator(name, rect, offset);
}

//----------------------------------------------------------------------------//
void Operatorset_xmlHandler::elementOperatorsetEnd()
{
    if (!d_operatorset)
        CEGUI_THROW(InvalidRequestException(
            "Operatorset_xmlHandler::elementOperatorsetEnd: "
            "Attempt to access null object."));

    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(d_operatorset));
    CEGUI::Logger::getSingleton().logEvent("Finished creation of Operatorset '" +
        d_operatorset->getName() + "' via XML file. " + addr_buff, CEGUI::Informative);
}

//----------------------------------------------------------------------------//

} // End of  ProcGen namespace section


PGOperatorsetManager.hpp

Code: Select all

#ifndef _PGOperatorsetManager_hpp_
#define _PGOperatorsetManager_hpp_

#include "PGOperatorset.hpp"
#include "PGOperatorset_xmlHandler.hpp"
#include "CEGUIBase.h"
#include "CEGUISingleton.h"
#include "CEGUINamedXMLResourceManager.h"
#include "CEGUIIteratorBase.h"

#if defined(_MSC_VER)
#   pragma warning(push)
#   pragma warning(disable : 4275)
#   pragma warning(disable : 4251)
#endif

// Start of ProcGen namespace section
namespace ProcGen
{
class Operatorset;
class Operatorset_xmlHandler;

/*!
\brief
    Class providing a shared library of Operatorset objects to the system.

    The OperatorsetManager is used to create, access, and destroy Operatorset objects.
    The idea is that the OperatorsetManager will function as a central repository
    for imagery used within the GUI system, and that such imagery can be
    accessed, via a unique name, by any interested party within the system.
*/
class OperatorsetManager :
        public CEGUI::Singleton<ProcGen::OperatorsetManager>,
      public CEGUI::NamedXMLResourceManager<ProcGen::Operatorset, ProcGen::Operatorset_xmlHandler>
{
public:
    //! Constructor for OperatorsetManager objects
    OperatorsetManager();

    //! Destructor for OperatorsetManager objects
    ~OperatorsetManager();

    /*!
    \brief
        Create a Operatorset object with the given name and Texture

        The created Operatorset will be of limited use, and will require one or
        more images to be defined for the set.

    \param name
        CEGUI::String object containing the unique name for the Operatorset being created.

    \param texture
        Texture object to be associated with the Operatorset

    \param action
        One of the CEGUI::XMLResourceExistsAction enumerated values indicating what
        action should be taken when an Operatorset with the specified name
        already exists.

    \return
        Reference to the newly created Operatorset object

    \exception AlreadyExistsException
        thrown if an Operatorset named \a name is already present in the system.
    */
    Operatorset& create(const CEGUI::String& name, CEGUI::Texture& texture,
                     CEGUI::XMLResourceExistsAction action = CEGUI::XREA_RETURN);

    /*!
    \brief
        Create an Operatorset object from the specified image file.  The Operatorset
        will initially have a single image defined named "full_image" which is
        an image that represents the entire area of the loaded image.

    \param name
        CEGUI::String object containing the unique name for the Operatorset being created.

    \param filename
        CEGUI::String object holding the name of the image file to be loaded.

    \param resourceGroup
        Resource group identifier to be passed to the resource manager when
        loading the image file.

    \param action
        One of the CEGUI::XMLResourceExistsAction enumerated values indicating what
        action should be taken when an Operatorset with the specified name
        already exists.

    \return
        Reference to the newly created Operatorset object

    \exception AlreadyExistsException
        thrown if an Operatorset named \a name is already present in the system.

    \exception FileIOException
        thrown if something goes wrong while reading the image file \a filename.
    */
    Operatorset& createFromImageFile(const CEGUI::String& name, const CEGUI::String& filename,
                                const CEGUI::String& resourceGroup = "",
                                CEGUI::XMLResourceExistsAction action = CEGUI::XREA_RETURN);

    /*!
    \brief
        Notify the OperatorsetManager that the display size may have changed.

    \param size
        CEGUI::Size object describing the display resolution
    */
    void notifyDisplaySizeChanged(const CEGUI::Size& size);

    /*!
    \brief
        Writes a full XML operatorset for the specified Operatorset to the given
        CEGUI::OutStream.

    \param operatorset
        CEGUI::String holding the name of the Operatorset to be written to the stream.

    \param out_stream
        CEGUI::OutStream (std::ostream based) object where data is to be sent.

    \return
        Nothing.
    */
    void writeOperatorsetToStream(const CEGUI::String& operatorset,
                               CEGUI::OutStream& out_stream) const;

    //! OperatorsetIterator type definition.
    typedef CEGUI::ConstBaseIterator<ObjectRegistry> OperatorsetIterator;

    /*!
    \brief
        Return a OperatorsetManager::OperatorsetIterator object to iterate over the
        available Operatorset objects.
    */
    OperatorsetIterator getIterator() const;

    // ensure we see overloads from template base class
    using CEGUI::NamedXMLResourceManager<Operatorset, Operatorset_xmlHandler>::create;
};

} // End of  ProcGen namespace section

#if defined(_MSC_VER)
#   pragma warning(pop)
#endif

#endif  // end of guard _PGOperatorsetManager_hpp_


PGOperatorsetManager.cpp

Code: Select all

#include "PGOperatorsetManager.hpp"
#include "CEGUIExceptions.h"
#include "CEGUILogger.h"

// Start of ProcGen namespace section
namespace ProcGen
{
//----------------------------------------------------------------------------//
// singleton instance pointer
template<> OperatorsetManager* CEGUI::Singleton<OperatorsetManager>::ms_Singleton = 0;

//----------------------------------------------------------------------------//
OperatorsetManager::OperatorsetManager() :
    CEGUI::NamedXMLResourceManager<Operatorset, Operatorset_xmlHandler>("Operators")
{
    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(this));
    CEGUI::Logger::getSingleton().logEvent(
        "CEGUI::OperatorsetManager singleton created " + CEGUI::String(addr_buff));
}

//----------------------------------------------------------------------------//
OperatorsetManager::~OperatorsetManager()
{
    CEGUI::Logger::getSingleton().logEvent(
        "---- Begining cleanup of Operatorset system ----");

    destroyAll();

    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(this));
    CEGUI::Logger::getSingleton().logEvent(
       "CEGUI::OperatorsetManager singleton destroyed " + CEGUI::String(addr_buff));
}

//----------------------------------------------------------------------------//
Operatorset& OperatorsetManager::create(const CEGUI::String& name, CEGUI::Texture& texture,
                                  CEGUI::XMLResourceExistsAction action)
{
    CEGUI::Logger::getSingleton().logEvent("Attempting to create Operatorset '" + name +
                                    "' with texture only.");

    // create new object ahead of time
    Operatorset* object = new Operatorset(name, texture);
    // return appropriate object instance (deleting any not required)
    return doExistingObjectAction(name, object, action);;
}

//----------------------------------------------------------------------------//
Operatorset& OperatorsetManager::createFromImageFile(const CEGUI::String& name,
                                               const CEGUI::String& filename,
                                               const CEGUI::String& resourceGroup,
                                               CEGUI::XMLResourceExistsAction action)
{
    CEGUI::Logger::getSingleton().logEvent("Attempting to create Operatorset '" + name +
        "' using image file '" + filename + "'.");

    // create new object ahead of time
    Operatorset* object = new Operatorset(name, filename, resourceGroup);
    // return appropriate object instance (deleting any not required)
    return doExistingObjectAction(name, object, action);;
}

//----------------------------------------------------------------------------//
void OperatorsetManager::notifyDisplaySizeChanged(const CEGUI::Size& size)
{
    // notify all attached Operatorset objects of the change in resolution
    ObjectRegistry::iterator pos = d_objects.begin(), end = d_objects.end();

    for (; pos != end; ++pos)
        pos->second->notifyDisplaySizeChanged(size);
}

//----------------------------------------------------------------------------//
OperatorsetManager::OperatorsetIterator OperatorsetManager::getIterator(void) const
{
    return OperatorsetIterator(d_objects.begin(), d_objects.end());
}

//----------------------------------------------------------------------------//
void OperatorsetManager::writeOperatorsetToStream(const CEGUI::String& operatorset,
                                            CEGUI::OutStream& out_stream) const
{
    // Create an CEGUI::XMLSerializer which make use of 4 space and UTF-8 encoding
    CEGUI::XMLSerializer xml(out_stream);
    get(operatorset).writeXMLToStream(xml);
}

//----------------------------------------------------------------------------//

} // End of  ProcGen namespace section


1> PGOperatorset_xmlHandler.cpp
1>c:\users\myuser\my documents\visual studio 2010\projects\procgen\src\PGOperatorset.hpp(36): error C2065: Operator: undefined identifier

Re: Help to reuse CEGUI classes

Posted: Tue Dec 28, 2010 10:57
by uelkfr
I have found error, but I don't understand why.

To successfully compile such code you need forward reference a class like this:

Code: Select all

namespace ProcGen
{
class Operatorset;

class Operator {
Operatorset* d_owner;
...


And you are not allowed to include each other's .h files between aggregated classes EVEN THOUGH YOU USE #ifndef HEADER GUARDS or #pragma once! I thought header guards saves from all problems, but this problem was new to me.

Re: Help to reuse CEGUI classes

Posted: Tue Dec 28, 2010 11:12
by Kulik
I smell circular dependency or header guard typo :-) Anyways forward declaring stuff like you did is the way to go, it speeds up compiling.

Re: Help to reuse CEGUI classes

Posted: Tue Dec 28, 2010 12:10
by uelkfr
Yes, maybe circular dependency. No header guard typo, because I even tried Microsoft specific #pragma once.

grrrrr:

Code: Select all

...
// Start of ProcGen namespace section
namespace ProcGen
{
//----------------------------------------------------------------------------//
// singleton instance pointer
template<> OperatorsetManager* CEGUI::Singleton<OperatorsetManager>::ms_Singleton = 0;
...


Code: Select all

c:\documents and settings\user\my documents\visual studio 2010\projects\procgen\src\pgoperatorsetmanager.cpp(10): error C2888: ProcGen::OperatorsetManager *CEGUI::Singleton<T>::ms_Singleton: symbol cannot be defined within namespace "ProcGen"
          with
          [
              T=ProcGen::OperatorsetManager
          ]


The most thing I don't like in C++ are templates. I even think what templates was wrong direction in C++ language evolution. I don't like STL and boost. If you look at Java or C# there are no templates.

Re: Help to reuse CEGUI classes

Posted: Tue Dec 28, 2010 12:30
by Mikademus
uelkfr wrote:... I even tried Microsoft specific #pragma once. ... The most thing I don't like in C++ are templates. I even think what templates was wrong direction in C++ language evolution. I don't like STL and boost. If you look at Java or C# there are no templates.


Wow, that was the most compact flamebait I ever saw! *applause*
Stock reply you will be likely to get from your kind of statement: "Then go back to your toy languages and toy programs and toy problems &$%$%#&&!!!!11shiftone".

A more reasonable reply: Templates is one of the most powerful features of C++. Complaining about them is like complaining about macros in Lisp, which is that language's most powerful feature, perhaps the most powerful feature of any programming language. Java has generics based on a limited subset of C++ templates. C# has template syntax based on C++ templates. The STL has been part of C++ since it was standardised and is the reason you have the greatest affluence of free libraries you can chose from today for any language. And boost has provided more language mechanisms for power users than any comparable project for any language and is a guarantee all additions to the language are extremely tested, stable, functional and useful.

Don't complain about the language without understanding what you're complaining about. And don't go into geek rage over being called ignorant and flame back. Learn the language instead.

Have fun! :pint:

Re: Help to reuse CEGUI classes

Posted: Tue Dec 28, 2010 13:09
by uelkfr
Flamebait is compact because my english is poor :)

Blender and Blender GUI is written in C. The libraries I and CEGUI use such as FREETYPE, EXPAT, ZLIB, PRCE, LUA, GLEW, GLFW, OpenGL, OpenCL also written in C.
Generics are better than templates I think. So you think new C++0x standart is the right direction? Its proposed mostly by boost community.

Fixed my issue moving ms_Singleton initialization outside ProcGen's namespace

Code: Select all

template<> ProcGen::OperatorsetManager* CEGUI::Singleton<ProcGen::OperatorsetManager>::ms_Singleton = 0;

But i'm not sure about not having problems with GCC and Intel C++ compiler. Need to test at ease.

Re: Help to reuse CEGUI classes

Posted: Tue Dec 28, 2010 13:41
by Kulik
<3 templates... Nuff said. And CEGUI is getting more and more insane templates thanks to me :lol:

C is also a great language. Always use the best tool for the job they say...

Re: Help to reuse CEGUI classes

Posted: Thu Dec 30, 2010 08:03
by uelkfr
I have almost integrated my classes, which are based on CEGUI classes. The last thing I can't implement is the automated interface to Lua. When I create .cpp and .h file using tolua++cegui_Static.exe I need make custom changes to these files.

=========================== start of LuaInterface.pkg =============================
// include the header that makes these files generate valid code
$#include "PGrequired.h"
$#include "required.h"
$#include "CEGUIPropertyHelper.h"

$pfile "Sample_FirstWindow.pkg"

namespace ProcGen
{
$pfile "PGOperator.pkg"
$pfile "PGOperatorset.pkg"
$pfile "PGOperatorsetManager.pkg"

$pfile "PGIterators.pkg"
}
============================= end of LuaInterface.pkg =============================

============================= start of PGOperator.pkg =============================
$#include "PGOperator.hpp"
class Operator
{
string getName() const;
string getOperatorsetName() const;
string getIcon(void) const;
};
=============================== end of PGOperator.pkg =============================

============================= start of PGOperatorset.pkg ===========================
$#include "PGOperatorset.hpp"
class Operatorset
{
string getName() const;
OperatorIterator getIterator() const;
};
============================== end of PGOperatorset.pkg ===========================

========================= start of PGOperatorsetManager.pkg ========================
$#include "PGOperatorsetManager.hpp"
class OperatorsetManager
{
static OperatorsetManager& getSingleton();

tolua_throws|CEGUI::Exception,error| Operatorset& create(utf8string filename, utf8string resourcegroup="", XMLResourceExistsAction action = XREA_RETURN);
};
========================= end of PGOperatorsetManager.pkg ========================

=============================== start of PGIterators.pkg ==========================
/************************************************************************
Lua iterator implementation
*************************************************************************/
$[

function ProcGen.iterator_impl_next(p)
if p:isAtEnd() then
return nil;
end
local k,v = p:key(), p:value();
p:next();
return k,v;
end

function ProcGen.iterator_impl(self)
return ProcGen.iterator_impl_next, self;
end

$]

/************************************************************************
OperatorIterator
*************************************************************************/
class OperatorIterator
{
string getCurrentKey @ key() const;
Operator getCurrentValue @ value() const;

bool isAtEnd() const;
bool isAtStart() const;

OperatorIterator& __operator_increment @ next();
OperatorIterator& __operator_decrement @ previous();
bool operator== (const OperatorIterator& rhs) const;

void toStart();
void toEnd();

OperatorIterator(const OperatorIterator& org);
};

// lua iterator
$[

ProcGen.OperatorIterator.iterator = ProcGen.iterator_impl;

$]
=============================== end of PGIterators.pkg ==========================

=============================== start of PGrequired.h ==========================
#include "PGOperatorset.hpp"
namespace ProcGen
{
/************************************************************************
Stuff needed to make the iterators work
*************************************************************************/
typedef Operatorset::OperatorIterator OperatorIterator;
}
=============================== end of PGrequired.h ==========================

=============================== start of make.bat ==========================
tolua++cegui_Static.exe -n LuaInterface -H LuaInterface.hpp -o LuaInterface.cpp -L ../lib/cegui/cegui/src/ScriptingModules/LuaScriptModule/package/exceptions.lua LuaInterface.pkg
================================ end of make.bat ==========================

After I get LuaInterface.cpp and LuaInterface.hpp, I always make following changes in LuaInterface.cpp:
1) comment XMLResourceExistsAction line, how it gets there? I couldn't see this in function tolua_reg_types() of lua_CEGUI.cpp
static void tolua_reg_types (lua_State* tolua_S)
{
tolua_usertype(tolua_S,"ProcGen::OperatorIterator");
tolua_usertype(tolua_S,"ProcGen::OperatorsetManager");
tolua_usertype(tolua_S,"ProcGen::Operator");
// tolua_usertype(tolua_S,"XMLResourceExistsAction");
tolua_usertype(tolua_S,"ProcGen::Operatorset");
}
2) add CEGUI:: namespace to XMLResourceExistsAction or remove this line
#ifndef TOLUA_DISABLE_tolua_LuaInterface_ProcGen_OperatorsetManager_create00
static int tolua_LuaInterface_ProcGen_OperatorsetManager_create00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"ProcGen::OperatorsetManager",0,&tolua_err) ||
!tolua_isutf8string(tolua_S,2,0,&tolua_err) ||
!tolua_isutf8string(tolua_S,3,1,&tolua_err) ||
!tolua_isusertype(tolua_S,4,"CEGUI::XMLResourceExistsAction",1,&tolua_err) ||
!tolua_isnoobj(tolua_S,5,&tolua_err)
)
goto tolua_lerror;
3) replace
// XMLResourceExistsAction action = *((XMLResourceExistsAction*) tolua_tousertype(tolua_S,4,(void*)&(const XMLResourceExistsAction)XREA_RETURN));
with
CEGUI::XMLResourceExistsAction action = ((CEGUI::XMLResourceExistsAction) (int) tolua_tonumber(tolua_S,10,CEGUI::XREA_RETURN));

I think i'm missing something, because I don't see such problems in lua_CEGUI.cpp. Please help.

Re: [Solved] Help to reuse CEGUI classes

Posted: Sat Jan 01, 2011 06:48
by uelkfr
I have just made some changes to .pkg files and now all works.

Code: Select all

...
namespace CEGUI
{
$pfile "../lib/cegui/cegui/src/ScriptingModules/LuaScriptModule/package/Basic.pkg"
}
...


Code: Select all

...
tolua_throws|CEGUI::Exception,error| Operatorset& create(utf8string filename, utf8string resourcegroup="", CEGUI::XMLResourceExistsAction action = CEGUI::XREA_RETURN);
...