- changed the design in Edjexx to return smart pointers

- now local save the pointer and return a reference
  - if failure throw an exception
- added some container memory helpers
- changed the example code


SVN revision: 55794
This commit is contained in:
Andreas Volz 2011-01-01 21:40:40 +00:00
parent d30f0fc1cb
commit 0366f62773
13 changed files with 269 additions and 82 deletions

View File

@ -32,6 +32,26 @@ private:
const std::string &txt;
};
class ExternalNotExistingException : public std::exception
{
public:
ExternalNotExistingException (const std::string &partname) : txt (partname) {}
const char* what () const throw ();
private:
const std::string &txt;
};
class SwallowNotExistingException : public std::exception
{
public:
SwallowNotExistingException (const std::string &partname) : txt (partname) {}
const char* what () const throw ();
private:
const std::string &txt;
};
} // end namespace Edjexx
#endif // EDJEXX_EXCEPTIONS_H

View File

@ -6,10 +6,10 @@
#include <map>
/* EFL++ */
#include <eflxx/Common.h>
#include <eflxx/CountedPtr.h>
#include <eflxx/Eflxx.h>
#include <evasxx/Evasxx.h>
#include <evasxx/Canvas.h>
/* local */
#include "Part.h"
/* EFL */
@ -69,13 +69,13 @@ public:
void recalculateLayout();
bool hasPart( const std::string &partname ) const;
Eflxx::CountedPtr <Part> operator[]( const std::string &partname );
Part &operator[]( const std::string &partname );
/*!
* @param partname Access a Part in the Object.
* @throw PartNotExistingException
*/
Eflxx::CountedPtr <Part> getPart( const std::string &partname );
Part &getPart( const std::string &partname );
/* signals and slots */
void connect (const std::string &emission, const std::string &source, const SignalSlot& slot);
@ -95,10 +95,13 @@ private:
Object( Evas_Object* object );
void deleteAllParts ();
bool operator=( const Object& );
bool operator==( const Object& );
std::map <std::pair <std::string, std::string>, SignalSignal*> mSignalList;
std::map <std::string, Part*> mPartList;
};

View File

@ -38,9 +38,9 @@ public:
void swallow( Evasxx::Object* );
void unswallow( Evasxx::Object* );
Eflxx::CountedPtr <Evasxx::Object> getSwallow ();
Evasxx::Object &getSwallow ();
Eflxx::CountedPtr <Evasxx::Object> getExternalObject ();
Evasxx::Object &getExternalObject ();
// TODO: wrap Param?
bool setParam (Edjexx::ExternalParam *param);
@ -48,8 +48,10 @@ public:
//const Evasxx::Object* getObject ( const char* name );
private:
Object* _parent;
const std::string &_partname;
Object* mParent;
const std::string &mPartname;
Evasxx::Object *mExternalObject;
Evasxx::Object *mSwallowObject;
/* State?
EAPI const char *edje_object_part_state_get (Evas_Object *obj, const char *part, double *val_ret);

View File

@ -9,7 +9,7 @@ namespace Edjexx {
const char* LoadException::what () const throw ()
{
static std::ostringstream os;
os << "EdjeObject file load error: filename: '"
os << "File load error: filename: '"
<< mFilename
<< "' groupname: '"
<< mGroupname
@ -22,7 +22,25 @@ const char* LoadException::what () const throw ()
const char* PartNotExistingException::what () const throw ()
{
std::ostringstream os;
os << "EdjeObject loaded with not existing part '";
os << "Edje part not existing: '";
os << txt.c_str (); // TODO: why is c_str() needed! -> rework Exception concept!
os << "'.";
return static_cast <const char*> (os.str ().c_str ());
}
const char* ExternalNotExistingException::what () const throw ()
{
std::ostringstream os;
os << "Edje external object not existing: '";
os << txt.c_str (); // TODO: why is c_str() needed! -> rework Exception concept!
os << "'.";
return static_cast <const char*> (os.str ().c_str ());
}
const char* SwallowNotExistingException::what () const throw ()
{
std::ostringstream os;
os << "Edje swallow object not existing: '";
os << txt.c_str (); // TODO: why is c_str() needed! -> rework Exception concept!
os << "'.";
return static_cast <const char*> (os.str ().c_str ());

View File

@ -62,7 +62,6 @@ Object::Object( Evasxx::Canvas &canvas, const Eflxx::Point &pos, const std::stri
Object::Object( Evas_Object* object)
{
o = object;
mFree = false;
}
Object::~Object()
@ -71,6 +70,11 @@ Object::~Object()
evas_object_del( o );
}
void Object::deleteAllParts ()
{
Eflxx::delete_stl_container (mPartList);
}
void Object::setFile( const std::string &filename, const std::string &groupname )
{
if (!edje_object_file_set( o, filename.c_str (), groupname.c_str () ))
@ -95,23 +99,36 @@ Eflxx::Size Object::getMaximumSize() const
return Eflxx::Size( w, h );
}
bool Object::hasPart( const std::string &partname ) const
bool Object::hasPart (const std::string &partname) const
{
return edje_object_part_exists( o, partname.c_str () );
}
Eflxx::CountedPtr <Edjexx::Part> Object::operator[]( const std::string &partname )
Part &Object::operator[]( const std::string &partname )
{
return getPart( partname );
}
Eflxx::CountedPtr <Part> Object::getPart( const std::string &partname )
Part &Object::getPart (const std::string &partname)
{
if ( hasPart( partname ) )
if (hasPart (partname))
{
Part* ep = new Part( this, partname );
return Eflxx::CountedPtr <Part> (ep);
Part *p;
map <std::string, Part*>::iterator partFound = mPartList.find (partname);
if (partFound != mPartList.end ()) // found
{
p = partFound->second;
}
else // not found
{
p = new Part (this, partname);
mPartList[partname] = p;
}
return *p;
}
throw PartNotExistingException (partname);
}

View File

@ -5,21 +5,28 @@
#include "../include/edjexx/Part.h"
#include "../include/edjexx/Object.h"
#include "../include/edjexx/ExternalParam.h"
#include "../include/edjexx/Exceptions.h"
/* STD */
#include <map>
namespace Edjexx {
Part::Part( Object* parent, const std::string &partname )
:_parent( parent), _partname( partname )
Part::Part (Object* parent, const std::string &partname) :
mParent (parent),
mPartname (partname),
mExternalObject (NULL),
mSwallowObject (NULL)
{
Dout( dc::notice, " Part::EdjePart( '" << _partname << "' ) constructing..." );
Dout( dc::notice, " Part::EdjePart( '" << mPartname << "' ) constructing..." );
}
Part::~Part()
{
Dout( dc::notice, "~Part::EdjePart( '" << _partname << "' ) destructing..." );
Dout( dc::notice, "~Part::EdjePart( '" << mPartname << "' ) destructing..." );
delete mExternalObject;
delete mSwallowObject;
}
Eflxx::Rect Part::getGeometry() const
@ -28,58 +35,70 @@ Eflxx::Rect Part::getGeometry() const
int y;
int w;
int h;
edje_object_part_geometry_get( _parent->obj(), _partname.c_str (), &x, &y, &w, &h );
edje_object_part_geometry_get (mParent->obj(), mPartname.c_str (), &x, &y, &w, &h);
return Eflxx::Rect( x, y, w, h );
}
void Part::setText( const std::string &text )
{
edje_object_part_text_set( _parent->obj(), _partname.c_str (), text.c_str () );
edje_object_part_text_set( mParent->obj(), mPartname.c_str (), text.c_str () );
}
const std::string Part::getText() const
{
return edje_object_part_text_get( _parent->obj(), _partname.c_str () );
return edje_object_part_text_get( mParent->obj(), mPartname.c_str () );
}
void Part::swallow( Evasxx::Object* object )
{
edje_object_part_swallow (_parent->obj(), _partname.c_str (), object->obj());
edje_object_part_swallow (mParent->obj(), mPartname.c_str (), object->obj());
}
void Part::unswallow( Evasxx::Object* object )
{
edje_object_part_unswallow( _parent->obj(), object->obj() );
edje_object_part_unswallow( mParent->obj(), object->obj() );
}
Eflxx::CountedPtr <Evasxx::Object> Part::getSwallow()
Evasxx::Object &Part::getSwallow()
{
Evas_Object *eo = edje_object_part_swallow_get (_parent->obj(), _partname.c_str ());
Evas_Object *eo = edje_object_part_swallow_get (mParent->obj(), mPartname.c_str ());
Evasxx::Object *ret_o = Evasxx::Object::wrap (eo);
if (!mSwallowObject)
{
mSwallowObject = Evasxx::Object::wrap (eo);
}
return Eflxx::CountedPtr <Evasxx::Object> (ret_o);
if (!mSwallowObject)
throw SwallowNotExistingException (mPartname);
return *mSwallowObject;
}
Eflxx::CountedPtr <Evasxx::Object> Part::getExternalObject ()
Evasxx::Object &Part::getExternalObject ()
{
Evas_Object *eo = edje_object_part_external_object_get (_parent->obj(), _partname.c_str ());
Evasxx::Object *ret_o = Evasxx::Object::wrap (eo);
Evas_Object *eo = edje_object_part_external_object_get (mParent->obj(), mPartname.c_str ());
if (!mExternalObject)
{
mExternalObject = Evasxx::Object::wrap (eo);
}
return Eflxx::CountedPtr <Evasxx::Object> (ret_o);
if (!mExternalObject)
throw ExternalNotExistingException (mPartname);
return *mExternalObject;
}
bool Part::setParam (Edjexx::ExternalParam *param)
{
return edje_object_part_external_param_set (_parent->obj (), _partname.c_str (), param->getRaw ());
return edje_object_part_external_param_set (mParent->obj (), mPartname.c_str (), param->getRaw ());
}
/*const Evasxx::Object* Part::getObject ( const char* name )
{
return Evasxx::Object::objectLink( edje_object_part_object_get( static_cast <const Evas_Object*> (_parent->obj()), name ) );
return Evasxx::Object::objectLink( edje_object_part_object_get( static_cast <const Evas_Object*> (mParent->obj()), name ) );
}*/
} // end namespace Edjexx

View File

@ -6,5 +6,6 @@
#include "Debug.h"
#include "DebugInternal.h"
#include "System.h"
#include "MemoryUtil.h"
#endif // EFLXX_H

View File

@ -5,6 +5,7 @@ libeflxx_HEADERS = \
DebugInternal.h \
System.h \
Debug.h \
MemoryUtil.h \
Eflxx.h
libeflxxdir = \

View File

@ -0,0 +1,46 @@
#ifndef LOCAL_UTIL_H
#define LOCAL_UTIL_H
/* STL */
#include <map>
namespace Eflxx {
// some generic template functions for delete algorithms
template <typename T>
void delete_one (T *t)
{
delete t;
t = NULL;
}
template <typename T>
void delete_array (T *t)
{
delete [] t;
t = NULL;
}
template <typename T>
void delete_stl_container (T &cnt)
{
for (typename T::iterator it = cnt.begin(); it != cnt.end(); ++it)
{
delete *it;
}
cnt.clear();
}
template <typename Key, typename T>
void delete_stl_container (std::map<Key, T> &cnt)
{
for (typename std::map<Key, T>::iterator it = cnt.begin(); it != cnt.end(); ++it)
{
delete it->second;
}
cnt.clear ();
}
} // end namespace Eflxx
#endif // LOCAL_UTIL_H

View File

@ -35,6 +35,7 @@ int main (int argc, char **argv)
Background *bg = Background::factory (*elmWin);
// TODO wrap this
Evas *e = evas_object_evas_get(bg->obj ());
// TODO: CountedPtr
@ -47,44 +48,84 @@ int main (int argc, char **argv)
edje->setLayer (0);
edje->show ();
// This access is type unsafe as a cast is done without checking prior the type!
Eflxx::CountedPtr <Evasxx::Object> ext_eo (edje->getPart ("Button01")->getExternalObject ());
Elmxx::Button *button = static_cast <Elmxx::Button*> (&(*ext_eo));
button->setLabel ("This is a changed button");
// This access is type unsafe as a cast is done without checking prior the type!
Eflxx::CountedPtr <Evasxx::Object> ext_eo2 (edje->getPart ("List01")->getExternalObject ());
Elmxx::List *list = static_cast <Elmxx::List*> (&(*ext_eo2));
assert (list->append ("1. Line", NULL, NULL));
assert (list->append ("2. Line", NULL, NULL));
assert (list->append ("3. Line", NULL, NULL));
assert (list->append ("4. Line", NULL, NULL));
list->go ();
// The code below accesses a Edje External widget (here: Elementary Progressbar) in a type save way
Eflxx::CountedPtr <Evasxx::Object> ext_eo3 (edje->getPart ("Progressbar01")->getExternalObject ());
cout << "Edje Widget type: " << ext_eo3->getType () << endl;
if (ext_eo3->getType () == "elm_widget")
try
{
Elmxx::Object *elm_object = static_cast <Elmxx::Object*> (&(*ext_eo3));
cout << "Elm Widget type: " << elm_object->getWidgetType () << endl;
if (elm_object->getWidgetType () == "progressbar")
{
Elmxx::Progressbar *progressbar = static_cast <Elmxx::Progressbar*> (elm_object);
progressbar->setLabel ("This is the status");
progressbar->setValue (0.5);
}
// This access is type unsafe as a cast is done without checking prior the type!
Evasxx::Object &ext_eo = edje->getPart ("Button01").getExternalObject ();
Elmxx::Button &button = *(static_cast <Elmxx::Button*> (&ext_eo));
button.setLabel ("This is a changed button");
}
catch (Edjexx::PartNotExistingException pne)
{
cerr << pne.what () << endl;
}
catch (Edjexx::ExternalNotExistingException ene)
{
cerr << ene.what () << endl;
}
try
{
// This access is type unsafe as a cast is done without checking prior the type!
Evasxx::Object &ext_eo2 = edje->getPart ("List01").getExternalObject ();
Elmxx::List &list = *(static_cast <Elmxx::List*> (&ext_eo2));
assert (list.append ("1. Line", NULL, NULL));
assert (list.append ("2. Line", NULL, NULL));
assert (list.append ("3. Line", NULL, NULL));
assert (list.append ("4. Line", NULL, NULL));
list.go ();
}
catch (Edjexx::PartNotExistingException pne)
{
cerr << pne.what () << endl;
}
catch (Edjexx::ExternalNotExistingException ene)
{
cerr << ene.what () << endl;
}
try
{
// The code below accesses a Edje External widget (here: Elementary Progressbar) in a type save way
Evasxx::Object &ext_eo3 = edje->getPart ("Progressbar01").getExternalObject ();
cout << "Edje Widget type: " << ext_eo3.getType () << endl;
if (ext_eo3.getType () == "elm_widget")
{
Elmxx::Object &elm_object = *(static_cast <Elmxx::Object*> (&ext_eo3));
cout << "Elm Widget type: " << elm_object.getWidgetType () << endl;
if (elm_object.getWidgetType () == "progressbar")
{
Elmxx::Progressbar &progressbar = *(static_cast <Elmxx::Progressbar*> (&elm_object));
progressbar.setLabel ("This is the status");
progressbar.setValue (0.5);
}
}
}
catch (Edjexx::PartNotExistingException pne)
{
cerr << pne.what () << endl;
}
catch (Edjexx::ExternalNotExistingException ene)
{
cerr << ene.what () << endl;
}
// This External access is save as it only calls the ExternalParam interface
Eflxx::CountedPtr <Edjexx::Part> part (edje->getPart ("Slider01"));
try
{
Edjexx::Part &part = edje->getPart ("Slider01");
Edjexx::ExternalParam param ("value", 5.0f);
Edjexx::ExternalParam param2 ("label", "Changed Slider Value");
Edjexx::ExternalParam param ("value", 5.0f);
Edjexx::ExternalParam param2 ("label", "Changed Slider Value");
part->setParam (&param);
part->setParam (&param2);
part.setParam (&param);
part.setParam (&param2);
}
catch (Edjexx::PartNotExistingException pne)
{
cerr << pne.what () << endl;
}
bg->setWeightHintSize (1.0, 1.0);
elmWin->addObjectResize (*bg);

View File

@ -222,14 +222,16 @@ public:
private:
void registerCallbacks();
void registerCallbacks ();
void unregisterCallbacks ();
static void dispatcher( void *data, Evas *evas, Evas_Object *evas_object, void *event_info);
protected:
// TODO: think about makeing init private and call it from Object constructor
// in the current design there's no need to call from child...
void init ();
Evas_Object* o;
bool mFree; /// @deprecated
private:

View File

@ -180,6 +180,8 @@ private:
Evas_Smart_Class sc;
CustomEventWrapMapType mCustomSignalMap;
bool mFree; /// @deprecated
};
} // end namespace Evasxx

View File

@ -23,13 +23,7 @@ Object::Object (Evas_Object *eo)
{
o = eo; // set member Evas_Edje*
mFree = false; // don't manage the object and free it at delete time
/* Set up magic object back link */
evas_object_data_set( o, "obj_c++", this );
/* Set up callbacks */
registerCallbacks();
init ();
}
Object *Object::wrap( Evas_Object* o )
@ -39,8 +33,6 @@ Object *Object::wrap( Evas_Object* o )
void Object::init ()
{
mFree = true; // manage the object and free it at delete time
/* Set up magic object back link */
evas_object_data_set( o, "obj_c++", this );
@ -51,6 +43,7 @@ void Object::init ()
Object::~Object()
{
Dout( dc::notice, *this << " Object::~Object" );
unregisterCallbacks ();
}
const std::string Object::getName() const
@ -374,7 +367,7 @@ Eflxx::CountedPtr <Canvas> Object::getEvas ()
}
// PRIVATE
void Object::registerCallbacks()
void Object::registerCallbacks ()
{
// TODO: think about if it's good design to register all at start
// does this cost performance?
@ -398,6 +391,28 @@ void Object::registerCallbacks()
evas_object_event_callback_add( o, EVAS_CALLBACK_IMAGE_PRELOADED, &dispatcher, reinterpret_cast<void*>( EVAS_CALLBACK_IMAGE_PRELOADED ) );
}
void Object::unregisterCallbacks ()
{
evas_object_event_callback_del (o, EVAS_CALLBACK_MOUSE_IN, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_MOUSE_OUT, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_MOUSE_DOWN, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_MOUSE_UP, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_MOUSE_MOVE, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_MOUSE_WHEEL, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_KEY_DOWN, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_KEY_UP, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_FREE, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_SHOW, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_HIDE, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_MOVE, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_RESIZE, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_RESTACK, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_DEL, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_HOLD, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_CHANGED_SIZE_HINTS, dispatcher);
evas_object_event_callback_del (o, EVAS_CALLBACK_IMAGE_PRELOADED, dispatcher);
}
//PRIVATE
void Object::dispatcher( void *data, Evas *evas, Evas_Object *evas_object, void *event_info )
{