instance.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2006-2011 by the FIFE team                              *
00003  *   http://www.fifengine.net                                              *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // Standard C++ library includes
00023 #include <iostream>
00024 
00025 // 3rd party library includes
00026 #include <SDL.h>
00027 
00028 // FIFE includes
00029 // These includes are split up in two parts, separated by one empty line
00030 // First block: files included from the FIFE root src directory
00031 // Second block: files included from the same folder
00032 #include "util/log/logger.h"
00033 #include "util/base/exception.h"
00034 #include "util/math/fife_math.h"
00035 #include "util/time/timemanager.h"
00036 #include "model/metamodel/grids/cellgrid.h"
00037 #include "model/metamodel/ipather.h"
00038 #include "model/metamodel/action.h"
00039 #include "model/metamodel/timeprovider.h"
00040 #include "model/structures/layer.h"
00041 #include "model/structures/map.h"
00042 #include "model/structures/instancetree.h"
00043 
00044 #include "instance.h"
00045 
00046 namespace FIFE {
00047     static Logger _log(LM_INSTANCE);
00048 
00049     class ActionInfo {
00050     public:
00051         ActionInfo(IPather* pather, const Location& curloc):
00052             m_action(NULL),
00053             m_target(NULL),
00054             m_speed(0),
00055             m_repeating(false),
00056             m_action_start_time(0),
00057             m_action_offset_time(0),
00058             m_prev_call_time(0),
00059             m_pather_session_id(-1),
00060             m_pather(pather),
00061             m_leader(NULL) {}
00062 
00063         ~ActionInfo() {
00064             if (m_pather_session_id != -1) {
00065                 m_pather->cancelSession(m_pather_session_id);
00066             }
00067             delete m_target;
00068             m_target = NULL;
00069         }
00070 
00071         // Current action, owned by object
00072         Action* m_action;
00073         // target location for ongoing movement
00074         Location* m_target;
00075         // current movement speed
00076         double m_speed;
00077         // should action be repeated? used only for non-moving actions, moving ones repeat until movement is finished
00078         bool m_repeating;
00079         // action start time (ticks)
00080         uint32_t m_action_start_time;
00081         // action offset time (ticks) for resuming an action
00082         uint32_t m_action_offset_time;
00083         // ticks since last call
00084         uint32_t m_prev_call_time;
00085         // session id for pather
00086         int32_t m_pather_session_id;
00087         // pather
00088         IPather* m_pather;
00089         // leader for follow activity
00090         Instance* m_leader;
00091     };
00092 
00093     class SayInfo {
00094     public:
00095         SayInfo(const std::string& txt, uint32_t duration):
00096             m_txt(txt),
00097             m_duration(duration),
00098             m_start_time(0) {}
00099 
00100         std::string m_txt;
00101         uint32_t m_duration;
00102         uint32_t m_start_time;
00103     };
00104 
00105     Instance::InstanceActivity::InstanceActivity(Instance& source):
00106         m_location(source.m_location),
00107         m_rotation(source.m_rotation),
00108         m_facinglocation(),
00109         m_action(),
00110         m_speed(0),
00111         m_timemultiplier(1.0),
00112         m_saytxt(""),
00113         m_changelisteners(),
00114         m_actionlisteners(),
00115         m_actioninfo(NULL),
00116         m_sayinfo(NULL),
00117         m_timeprovider(NULL),
00118         m_blocking(source.m_blocking) {
00119         if (source.m_facinglocation) {
00120             m_facinglocation = *source.m_facinglocation;
00121         }
00122     }
00123 
00124     Instance::InstanceActivity::~InstanceActivity() {
00125         delete m_actioninfo;
00126         delete m_sayinfo;
00127         delete m_timeprovider;
00128     }
00129 
00130     void Instance::InstanceActivity::update(Instance& source) {
00131         source.m_changeinfo = ICHANGE_NO_CHANGES;
00132         if (m_location != source.m_location) {
00133             source.m_changeinfo |= ICHANGE_LOC;
00134             if (m_location.getLayerCoordinates() != source.m_location.getLayerCoordinates()) {
00135                 source.m_changeinfo |= ICHANGE_CELL;
00136             }
00137             m_location = source.m_location;
00138         }
00139         if (m_rotation != source.m_rotation) {
00140             source.m_changeinfo |= ICHANGE_ROTATION;
00141             m_rotation = source.m_rotation;
00142         }
00143         if (source.m_facinglocation && (m_facinglocation != *source.m_facinglocation)) {
00144             source.m_changeinfo |= ICHANGE_FACING_LOC;
00145             m_facinglocation = *source.m_facinglocation;
00146         }
00147         if (m_actioninfo && (m_speed != m_actioninfo->m_speed)) {
00148             source.m_changeinfo |= ICHANGE_SPEED;
00149             m_speed = m_actioninfo->m_speed;
00150         }
00151         if (m_actioninfo && (m_action != m_actioninfo->m_action)) {
00152             source.m_changeinfo |= ICHANGE_ACTION;
00153             m_action = m_actioninfo->m_action;
00154         }
00155         if (m_timeprovider && (m_timemultiplier != m_timeprovider->getMultiplier())) {
00156             source.m_changeinfo |= ICHANGE_TIME_MULTIPLIER;
00157             m_timemultiplier = m_timeprovider->getMultiplier();
00158         }
00159         if (m_sayinfo && (m_saytxt != m_sayinfo->m_txt)) {
00160             source.m_changeinfo |= ICHANGE_SAYTEXT;
00161             m_saytxt = m_sayinfo->m_txt;
00162         }
00163         if (m_blocking != source.m_blocking) {
00164             source.m_changeinfo |= ICHANGE_BLOCK;
00165             m_blocking = source.m_blocking;
00166         }
00167 
00168         if (source.m_changeinfo != ICHANGE_NO_CHANGES) {
00169             std::vector<InstanceChangeListener*>::iterator i = m_changelisteners.begin();
00170             while (i != m_changelisteners.end()) {
00171                 if (NULL != *i)
00172                 {
00173                     (*i)->onInstanceChanged(&source, source.m_changeinfo);
00174                 }
00175                 ++i;
00176             }
00177             // Really remove "removed" listeners.
00178             m_changelisteners.erase(
00179                 std::remove(m_changelisteners.begin(),m_changelisteners.end(),
00180                     (InstanceChangeListener*)NULL),
00181                 m_changelisteners.end());
00182         }
00183     }
00184 
00185     Instance::Instance(Object* object, const Location& location, const std::string& identifier):
00186         m_id(identifier),
00187         m_rotation(0),
00188         m_activity(NULL),
00189         m_changeinfo(ICHANGE_NO_CHANGES),
00190         m_object(object),
00191         m_location(location),
00192         m_facinglocation(NULL),
00193         m_visual(NULL),
00194         m_blocking(object->isBlocking()),
00195         m_override_blocking(false) {
00196     }
00197 
00198     Instance::~Instance() {
00199         std::vector<InstanceDeleteListener *>::iterator itor;
00200         for(itor = m_deletelisteners.begin(); itor != m_deletelisteners.end(); ++itor) {
00201             if (*itor != NULL) {
00202                 (*itor)->onInstanceDeleted(this);
00203             }
00204         }
00205 
00206         if(m_activity && m_activity->m_actioninfo) {
00207             // Don't ditribute onActionFinished in case we're already
00208             // deleting.
00209             m_activity->m_actionlisteners.clear();
00210             finalizeAction();
00211         }
00212 
00213         delete m_activity;
00214         delete m_facinglocation;
00215         delete m_visual;
00216     }
00217 
00218     void Instance::initializeChanges() {
00219         if (!m_activity) {
00220             m_activity = new InstanceActivity(*this);
00221             if(m_location.getLayer()) {
00222                 m_location.getLayer()->setInstanceActivityStatus(this, true);
00223             }
00224         }
00225     }
00226 
00227     bool Instance::isActive() const {
00228         return (m_activity != 0);
00229     }
00230 
00231     void Instance::setLocation(const Location& loc) {
00232         // ToDo: Handle the case when the layers are different
00233         if(m_location != loc) {
00234             if(isActive()) {
00235                 if (m_location.getLayerCoordinates() != loc.getLayerCoordinates()) {
00236                     m_location.getLayer()->getInstanceTree()->removeInstance(this);
00237                     m_location = loc;
00238                     m_location.getLayer()->getInstanceTree()->addInstance(this);
00239                 } else {
00240                     m_location = loc;
00241                 }
00242                 refresh();
00243             } else {
00244                 initializeChanges();
00245                 if (m_location.getLayerCoordinates() != loc.getLayerCoordinates()) {
00246                     m_location.getLayer()->getInstanceTree()->removeInstance(this);
00247                     m_location = loc;
00248                     m_location.getLayer()->getInstanceTree()->addInstance(this);
00249                 } else {
00250                     m_location = loc;
00251                 }
00252             }
00253         }
00254     }
00255 
00256     void Instance::setRotation(int32_t rotation) {
00257         if(m_rotation != rotation) {
00258             if(isActive()) {
00259                 m_rotation = rotation;
00260                 refresh();
00261             } else {
00262                 initializeChanges();
00263                 m_rotation = rotation;
00264             }
00265         }
00266     }
00267 
00268     void Instance::setId(const std::string& identifier) {
00269         m_id = identifier;
00270     }
00271 
00272     void Instance::setBlocking(bool blocking) {
00273         if (m_override_blocking) {
00274             m_blocking = blocking;
00275         }
00276     }
00277 
00278     bool Instance::isBlocking() const {
00279         return m_blocking;
00280     }
00281 
00282     void Instance::addActionListener(InstanceActionListener* listener) {
00283         initializeChanges();
00284         m_activity->m_actionlisteners.push_back(listener);
00285     }
00286 
00287     void Instance::removeActionListener(InstanceActionListener* listener) {
00288         if (!m_activity) {
00289             return;
00290         }
00291         std::vector<InstanceActionListener*>::iterator i = m_activity->m_actionlisteners.begin();
00292         while (i != m_activity->m_actionlisteners.end()) {
00293             if ((*i) == listener) {
00294                 *i = NULL;
00295                 return;
00296             }
00297             ++i;
00298         }
00299         FL_WARN(_log, "Cannot remove unknown listener");
00300     }
00301 
00302     void Instance::addChangeListener(InstanceChangeListener* listener) {
00303         initializeChanges();
00304         m_activity->m_changelisteners.push_back(listener);
00305     }
00306 
00307     void Instance::callOnActionFrame(Action* action, int32_t frame) {
00308         if (!m_activity) {
00309             return;
00310         }
00311 
00312         std::vector<InstanceActionListener*>::iterator i = m_activity->m_actionlisteners.begin();
00313         while (i != m_activity->m_actionlisteners.end()) {
00314             if(*i) {
00315                 (*i)->onInstanceActionFrame(this, action, frame);
00316             }
00317             ++i;
00318         }
00319     }
00320 
00321     void Instance::removeChangeListener(InstanceChangeListener* listener) {
00322         if (!m_activity) {
00323             return;
00324         }
00325         std::vector<InstanceChangeListener*>::iterator i = m_activity->m_changelisteners.begin();
00326         while (i != m_activity->m_changelisteners.end()) {
00327             if ((*i) == listener) {
00328                 *i = NULL;
00329                 return;
00330             }
00331             ++i;
00332         }
00333         FL_WARN(_log, "Cannot remove unknown listener");
00334     }
00335     void Instance::initializeAction(const std::string& action_name) {
00336         assert(m_object);
00337         assert(m_activity);
00338         const Action *old_action = m_activity->m_actioninfo ? m_activity->m_actioninfo->m_action : NULL;
00339         if (m_activity->m_actioninfo) {
00340             delete m_activity->m_actioninfo;
00341             m_activity->m_actioninfo = NULL;
00342         }
00343         m_activity->m_actioninfo = new ActionInfo(m_object->getPather(), m_location);
00344         m_activity->m_actioninfo->m_action = m_object->getAction(action_name);
00345         if (!m_activity->m_actioninfo->m_action) {
00346             delete m_activity->m_actioninfo;
00347             m_activity->m_actioninfo = NULL;
00348             throw NotFound(std::string("action ") + action_name + " not found");
00349         }
00350         m_activity->m_actioninfo->m_prev_call_time = getRuntime();
00351         if (m_activity->m_actioninfo->m_action != old_action) {
00352             m_activity->m_actioninfo->m_action_start_time = m_activity->m_actioninfo->m_prev_call_time;
00353         }
00354     }
00355 
00356     void Instance::move(const std::string& action_name, const Location& target, const double speed) {
00357         initializeChanges();
00358         initializeAction(action_name);
00359         m_activity->m_actioninfo->m_target = new Location(target);
00360         m_activity->m_actioninfo->m_speed = speed;
00361         setFacingLocation(target);
00362         FL_DBG(_log, LMsg("starting action ") <<  action_name << " from" << m_location << " to " << target << " with speed " << speed);
00363     }
00364 
00365     void Instance::follow(const std::string& action_name, Instance* leader, const double speed) {
00366         initializeChanges();
00367         initializeAction(action_name);
00368         m_activity->m_actioninfo->m_target = new Location(leader->getLocationRef());
00369         m_activity->m_actioninfo->m_speed = speed;
00370         m_activity->m_actioninfo->m_leader = leader;
00371         leader->addDeleteListener(this);
00372         setFacingLocation(*m_activity->m_actioninfo->m_target);
00373         FL_DBG(_log, LMsg("starting action ") <<  action_name << " from" << m_location << " to " << *m_activity->m_actioninfo->m_target << " with speed " << speed);
00374     }
00375 
00376     void Instance::act(const std::string& action_name, const Location& direction, bool repeating) {
00377         initializeChanges();
00378         initializeAction(action_name);
00379         m_activity->m_actioninfo->m_repeating = repeating;
00380         setFacingLocation(direction);
00381     }
00382 
00383     void Instance::say(const std::string& text, uint32_t duration) {
00384         initializeChanges();
00385         delete m_activity->m_sayinfo;
00386         m_activity->m_sayinfo = NULL;
00387 
00388         if (text != "") {
00389             m_activity->m_sayinfo = new SayInfo(text, duration);
00390             m_activity->m_sayinfo->m_start_time = getRuntime();
00391         }
00392     }
00393 
00394     const std::string* Instance::getSayText() const {
00395         if (m_activity && m_activity->m_sayinfo) {
00396             return &m_activity->m_sayinfo->m_txt;
00397         }
00398         return NULL;
00399     }
00400 
00401     void Instance::setFacingLocation(const Location& loc) {
00402         if (!m_facinglocation) {
00403             m_facinglocation = new Location(loc);
00404         } else {
00405             *m_facinglocation = loc;
00406         }
00407     }
00408 
00409     bool Instance::process_movement() {
00410 //      FL_DBG(_log, "Moving...");
00411         ActionInfo* info = m_activity->m_actioninfo;
00412         // timeslice for this movement
00413         uint32_t timedelta = m_activity->m_timeprovider->getGameTime() - info->m_prev_call_time;
00414 //      FL_DBG(_log, LMsg("timedelta ") <<  timedelta << " prevcalltime " << info->m_prev_call_time);
00415         // how far we can travel
00416         double distance_to_travel = (static_cast<double>(timedelta) / 1000.0) * info->m_speed;
00417 //      FL_DBG(_log, LMsg("dist ") <<  distance_to_travel);
00418 
00419         Location nextLocation = m_location;
00420         info->m_pather_session_id = info->m_pather->getNextLocation(
00421             this, *info->m_target,
00422             distance_to_travel, nextLocation, *m_facinglocation,
00423             info->m_pather_session_id);
00424         m_location.getLayer()->getInstanceTree()->removeInstance(this);
00425         m_location = nextLocation;
00426         //ExactModelCoordinate a = nextLocation.getMapCoordinates();
00427         //ExactModelCoordinate b = m_actioninfo->m_target->getMapCoordinates();
00428         m_location.getLayer()->getInstanceTree()->addInstance(this);
00429         // return if we are close enough to target to stop
00430         if (info->m_pather_session_id == -1) {
00431             return true;
00432         }
00433         return false;
00434     }
00435 
00436     InstanceChangeInfo Instance::update() {
00437         if (!m_activity) {
00438             return ICHANGE_NO_CHANGES;
00439         }
00440         // remove DeleteListeners
00441         m_deletelisteners.erase(std::remove(m_deletelisteners.begin(),m_deletelisteners.end(),
00442                 (InstanceDeleteListener*)NULL), m_deletelisteners.end());
00443         m_activity->update(*this);
00444         if (!m_activity->m_timeprovider) {
00445             bindTimeProvider();
00446         }
00447         ActionInfo* info = m_activity->m_actioninfo;
00448         if (info) {
00449 //          FL_DBG(_log, "updating instance");
00450 
00451             if (info->m_target) {
00452 //              FL_DBG(_log, "action contains target for movement");
00453                 // update target if needed
00454                 if (info->m_leader && (info->m_leader->getLocationRef() != *info->m_target)) {
00455                     *info->m_target = info->m_leader->getLocation();
00456                 }
00457                 bool movement_finished = process_movement();
00458                 if (movement_finished) {
00459 //                  FL_DBG(_log, "movement finished");
00460                     finalizeAction();
00461                 }
00462             } else {
00463 //              FL_DBG(_log, "action does not contain target for movement");
00464                 if (m_activity->m_timeprovider->getGameTime() - info->m_action_start_time + info->m_action_offset_time >= info->m_action->getDuration()) {
00465                     if (info->m_repeating) {
00466                         info->m_action_start_time = m_activity->m_timeprovider->getGameTime();
00467                         // prock: offset no longer needed
00468                         info->m_action_offset_time = 0;
00469                     } else {
00470                         finalizeAction();
00471                     }
00472                 }
00473             }
00474 
00475             // previous code may invalidate actioninfo.
00476             if( m_activity->m_actioninfo ) {
00477                 m_activity->m_actioninfo->m_prev_call_time = m_activity->m_timeprovider->getGameTime();
00478             }
00479         }
00480         if (m_activity->m_sayinfo) {
00481             if (m_activity->m_sayinfo->m_duration > 0) {
00482                 if (m_activity->m_timeprovider->getGameTime() >= m_activity->m_sayinfo->m_start_time + m_activity->m_sayinfo->m_duration) {
00483                     say("");
00484                 }
00485             }
00486         } else if (!m_activity->m_actioninfo && m_changeinfo == ICHANGE_NO_CHANGES && m_activity->m_actionlisteners.empty()) {
00487             // delete superfluous activity
00488             delete m_activity;
00489             m_activity = 0;
00490             return ICHANGE_NO_CHANGES;
00491         }
00492         return m_changeinfo;
00493     }
00494 
00495     void Instance::finalizeAction() {
00496         FL_DBG(_log, "finalizing action");
00497         assert(m_activity);
00498         assert(m_activity->m_actioninfo);
00499 
00500         if( m_activity->m_actioninfo->m_leader ) {
00501             m_activity->m_actioninfo->m_leader->removeDeleteListener(this);
00502         }
00503 
00504         Action* action = m_activity->m_actioninfo->m_action;
00505         delete m_activity->m_actioninfo;
00506         m_activity->m_actioninfo = NULL;
00507 
00508         std::vector<InstanceActionListener*>::iterator i = m_activity->m_actionlisteners.begin();
00509         while (i != m_activity->m_actionlisteners.end()) {
00510             if(*i)
00511                 (*i)->onInstanceActionFinished(this, action);
00512             ++i;
00513         }
00514         m_activity->m_actionlisteners.erase(
00515             std::remove(m_activity->m_actionlisteners.begin(),
00516                 m_activity->m_actionlisteners.end(),
00517                 (InstanceActionListener*)NULL),
00518             m_activity->m_actionlisteners.end());
00519     }
00520 
00521     Action* Instance::getCurrentAction() const {
00522         if (m_activity && m_activity->m_actioninfo) {
00523             return m_activity->m_actioninfo->m_action;
00524         }
00525         return NULL;
00526     }
00527 
00528     Location Instance::getTargetLocation() const {
00529         if (m_activity && m_activity->m_actioninfo && m_activity->m_actioninfo->m_target) {
00530             return *m_activity->m_actioninfo->m_target;
00531         }
00532         return m_location;
00533     }
00534 
00535     double Instance::getMovementSpeed() const {
00536         if (m_activity && m_activity->m_actioninfo) {
00537             return m_activity->m_actioninfo->m_speed;
00538         }
00539         return 0;
00540     }
00541 
00542     Location Instance::getFacingLocation() {
00543         return this->getFacingLocationRef();
00544     }
00545 
00546     Location& Instance::getFacingLocationRef() {
00547         if (!m_facinglocation) {
00548             m_facinglocation = new Location(m_location);
00549             m_facinglocation->setExactLayerCoordinates(m_facinglocation->getExactLayerCoordinates() + ExactModelCoordinate(1.0, 0.0));
00550             //m_facinglocation->setLayerCoordinates(ModelCoordinate(1,0));
00551         }
00552         return *m_facinglocation;
00553     }
00554 
00555     uint32_t Instance::getActionRuntime() {
00556         if (m_activity && m_activity->m_actioninfo) {
00557             if(!m_activity->m_timeprovider)
00558                 bindTimeProvider();
00559             return m_activity->m_timeprovider->getGameTime() - m_activity->m_actioninfo->m_action_start_time + m_activity->m_actioninfo->m_action_offset_time;
00560         }
00561         return getRuntime();
00562     }
00563 
00564     void Instance::setActionRuntime(uint32_t time_offset) {
00565         m_activity->m_actioninfo->m_action_offset_time = time_offset;
00566     }
00567 
00568     void Instance::bindTimeProvider() {
00569         float multiplier = 1.0;
00570         if (m_activity->m_timeprovider) {
00571             multiplier = m_activity->m_timeprovider->getMultiplier();
00572         }
00573         delete m_activity->m_timeprovider;
00574         m_activity->m_timeprovider = NULL;
00575 
00576         if (m_location.getLayer()) {
00577             Map* map = m_location.getLayer()->getMap();
00578             if (map) {
00579                 m_activity->m_timeprovider = new TimeProvider(map->getTimeProvider());
00580             }
00581         }
00582         if (!m_activity->m_timeprovider) {
00583             m_activity->m_timeprovider = new TimeProvider(NULL);
00584         }
00585         m_activity->m_timeprovider->setMultiplier(multiplier);
00586     }
00587 
00588     void Instance::refresh() {
00589         initializeChanges();
00590         bindTimeProvider();
00591     }
00592 
00593     void Instance::setTimeMultiplier(float multip) {
00594         initializeChanges();
00595         if (!m_activity->m_timeprovider) {
00596             bindTimeProvider();
00597         }
00598         m_activity->m_timeprovider->setMultiplier(multip);
00599     }
00600 
00601     float Instance::getTimeMultiplier() {
00602         if (m_activity && m_activity->m_timeprovider) {
00603             return m_activity->m_timeprovider->getMultiplier();
00604         }
00605         return 1.0;
00606     }
00607 
00608     float Instance::getTotalTimeMultiplier() {
00609         if (m_activity && m_activity->m_timeprovider) {
00610             return m_activity->m_timeprovider->getTotalMultiplier();
00611         }
00612         if (m_location.getLayer()) {
00613             Map* map = m_location.getLayer()->getMap();
00614             if (map && map->getTimeProvider()) {
00615                 return map->getTimeProvider()->getTotalMultiplier();
00616             }
00617         }
00618         return 1.0;
00619     }
00620 
00621     uint32_t Instance::getRuntime() {
00622         if (m_activity) {
00623             if(!m_activity->m_timeprovider)
00624                 bindTimeProvider();
00625             return m_activity->m_timeprovider->getGameTime();
00626         }
00627         if (m_location.getLayer()) {
00628             Map* map = m_location.getLayer()->getMap();
00629             if (map && map->getTimeProvider()) {
00630                 return map->getTimeProvider()->getGameTime();
00631             }
00632         }
00633         return TimeManager::instance()->getTime();
00634     }
00635 
00636     void Instance::addDeleteListener(InstanceDeleteListener *listener) {
00637         m_deletelisteners.push_back(listener);
00638     }
00639 
00640     void Instance::removeDeleteListener(InstanceDeleteListener *listener) {
00641         if (!m_deletelisteners.empty()) {
00642             std::vector<InstanceDeleteListener*>::iterator itor;
00643             itor = std::find(m_deletelisteners.begin(), m_deletelisteners.end(), listener);
00644             if(itor != m_deletelisteners.end()) {
00645                 if ((*itor) == listener) {
00646                     *itor = NULL;
00647                     return;
00648                 }
00649             } else {
00650                 FL_WARN(_log, "Cannot remove unknown listener");
00651             }
00652         }
00653     }
00654 
00655     void Instance::onInstanceDeleted(Instance* instance) {
00656         if(m_activity && m_activity->m_actioninfo &&
00657             m_activity->m_actioninfo->m_leader == instance) {
00658                 m_activity->m_actioninfo->m_leader = NULL;
00659         }
00660     }
00661 }