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 }
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.