object.cpp

Go to the documentation of this file.
00001 /*
00002   libwt - Vassilis Virvilis Toolkit - a widget library
00003   Copyright (C) 2006 Vassilis Virvilis <vasvir2@fastmail.fm>
00004  
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009   
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014   
00015   You should have received a copy of the GNU Lesser General Public
00016   License along with this library; if not, write to the
00017   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018   Boston, MA  02111-1307, SA.
00019 */
00020 
00021 #include "sdltimer.h"
00022 
00023 #include <wt/trace.h>
00024 #include <wt/application.h>
00025 #include <wt/event.h>
00026 #include <wt/object.h>
00027 
00028 namespace Wt {
00029 
00030 Object::Object(Object *parent, const std::string &name) :
00031         parent_(parent),
00032 name_(name) {
00033     trace("obj") << "Creating " << this << std::endl;
00034     if (parent_)
00035         parent_->insertChild(this);
00036 }
00037 
00038 Object::~Object() {
00039     trace("obj") << "Entering Destructor for " <<  this << std::endl;
00040     destroyed(this);
00041     // delete childs
00042     while (!children_.empty()) {
00043         Object *child = *children_.begin();
00044         trace("obj") << "Deleting child " << child << std::endl;
00045         delete child;
00046     }
00047 
00048     if (parent_)
00049         parent_->removeChild(this);
00050 
00051     // kill all pending timers
00052     killTimers();
00053 
00054     // this is to signal queue to not deliver any message to this object
00055 
00056     // from this point on it is not possible to deliver any SDLTimeEvent
00057     // in the SDL stack. We only have to take care the interval == 0 case.
00058     // Actually we don't have to do that either because rescheduling happens
00059     // on the same level with the timer event and we are not going to get
00060     // anymore of that after the next statement.
00061     Event *child_event = new ChildEvent(Event::ChildRemoved, this);
00062     Application::postEvent(0, child_event);
00063     trace("obj") << "Destroyed " <<  this << std::endl;
00064     Application::sendPostedEvents();
00065 }
00066 
00067 bool Object::isDescendant(const Object *p) const {
00068     if (!p)
00069         return false;
00070 
00071     const Object *q = this;
00072 
00073     do {
00074         if (p == q)
00075             return true;
00076     } while ((q = q->parent()));
00077 
00078     return false;
00079 }
00080 
00081 void Object::insertChild(Object *obj) {
00082     children_.push_back(obj);
00083     obj->parent_ = this;
00084     Event *child_event = new ChildEvent(Event::ChildInserted, obj);
00085     Application::postEvent(this, child_event);
00086 }
00087 
00088 void Object::removeChild(Object *obj) {
00089     List::iterator end = children_.end();
00090     List::iterator p = find(children_.begin(), end, obj);
00091 
00092     if (p != end) {
00093         children_.erase(p);
00094         obj->parent_ = 0;
00095         Event *child_event = new ChildEvent(Event::ChildRemoved, obj);
00096         Application::postEvent(this, child_event);
00097     }
00098 }
00099 
00100 void Object::reparent(Object *new_parent) {
00101     if (parent_ == new_parent)
00102         return;
00103     trace("obj") << "Reparenting " <<  this << std::endl;
00104 
00105     if (parent_) {
00106         trace("obj") << "   Leaving parent " <<  parent_ << std::endl;
00107         parent_->removeChild(this);
00108     }
00109     if (new_parent) {
00110         trace("obj") << "   Going to new parent " <<  new_parent << std::endl;
00111         new_parent->insertChild(this);
00112     }
00113     parent_ = new_parent;
00114 }
00115 
00116 Object *Object::topParent() const {
00117     const Object *p = this;
00118     while (p->parent_) {
00119         p = p->parent_;
00120     }
00121     return const_cast<Object *>(p);
00122 }
00123 
00124 void Object::installEventFilter(const Object *filterObj) {
00125     // we have to deconstify here. We cannot deliver event to const objects
00126     Object *obj = const_cast<Object *>(filterObj);
00127     eventFilters_.push_back(obj);
00128     obj->destroyed.connect(sigc::slot1<void, const Object *>(
00129                                sigc::mem_fun(*this, &Object::removeEventFilter)));
00130 }
00131 
00132 void Object::removeEventFilter(const Object *obj) {
00133     List::iterator p, end(eventFilters_.end());
00134     p = find(eventFilters_.begin(), end, obj);
00135     if (p != end)
00136         eventFilters_.erase(p);
00137 }
00138 
00139 int Object::startTimer(int interval) {
00140     int id = timers_.size() + 1;
00141     timers_[id] = new SDLTimer(this, id, interval);
00142     return id;
00143 }
00144 
00145 void Object::killTimer(int id) {
00146     delete timers_[id];
00147     timers_.erase(id);
00148 }
00149 
00150 void Object::killTimers() {
00151     uint n = timers_.size() + 1;
00152     for (uint i = 1; i < n; i++) {
00153         delete timers_[i];
00154     }
00155     timers_.clear();
00156 }
00157 
00158 /// check if SDL timer still exists
00159 SDLTimer *Object::timer(int id) const {
00160     SDLTimerPtrMap::const_iterator it = timers_.find(id);
00161     return (it != timers_.end() ? it->second : 0);
00162 }
00163 
00164 bool Object::filterEvent(Event *e) {
00165     for (List::iterator filter(eventFilters_.begin()),
00166             end(eventFilters_.end()); filter != end; ++filter) {
00167         if ((*filter)->eventFilter(this, e))
00168             return true;
00169     }
00170     return false;
00171 }
00172 
00173 bool Object::event(Event *e) {
00174     bool handled = true;
00175 
00176     if (filterEvent(e))
00177         return true;
00178 
00179     switch (e->type()) {
00180     case Event::Timer: {
00181             TimerEvent *te = static_cast<TimerEvent *>(e);
00182             int id = te->timerid();
00183             if (timer(id)) {
00184                 timerEvent(te);
00185             }
00186             // if it is signle shot it may have been killed
00187             // during eventhandling
00188             SDLTimer *t = timer(id);
00189             if (t)
00190                 t->scheduleNext();
00191         }
00192         break;
00193     case Event::ChildInserted:
00194     case Event::ChildRemoved:
00195         childEvent(static_cast<ChildEvent *>(e));
00196         break;
00197     default:
00198         if (e->type() >= Event::User) {
00199             customEvent(static_cast<CustomEvent *>(e));
00200         } else {
00201             handled = false;
00202         }
00203         break;
00204     }
00205 
00206     return handled;
00207 }
00208 
00209 std::ostream& operator<<(std::ostream& s, const Object* obj) {
00210     const std::string& nm = (obj) ? obj->name() : "(null)";
00211     s << "object: " << nm << " ("
00212     << static_cast<const void *>(obj) << ") parent: ";
00213     const Object *parent = (obj) ? obj->parent() : 0;
00214     if (parent)
00215         s << parent->name() <<
00216         " (" << (void *) parent << ")";
00217     else
00218         s << "none (0)";
00219 
00220     return s;
00221 }
00222 
00223 std::ostream& operator<<(std::ostream& s, const Object& ref) {
00224     return s << &ref;
00225 }
00226 
00227 std::ostream& operator<<(std::ostream& s, const Event* e) {
00228     s << "Event " << static_cast<const void *>(e) << " type: " << e->type();
00229     return s;
00230 }
00231 
00232 std::ostream& operator<<(std::ostream& s, const Event& e) {
00233     return s << &e;
00234 }
00235 
00236 }

Generated Fri Jul 28 19:23:00 2006.
Copyright © 1998-2003 by the respective authors.

This document is licensed under the terms of the GNU Free Documentation License and may be freely distributed under the conditions given by this license.