Gnash 0.8.10dev
ExecutableCode.h
Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
00003 // 
00004 // This program is free software; you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation; either version 3 of the License, or
00007 // (at your option) any later version.
00008 // 
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017 
00018 
00019 #ifndef GNASH_EXECUTABLECODE_H
00020 #define GNASH_EXECUTABLECODE_H
00021 
00022 #include <vector>
00023 #include <boost/noncopyable.hpp>
00024 
00025 #include "ActionExec.h"
00026 #include "Global_as.h"
00027 #include "fn_call.h"
00028 
00029 namespace gnash {
00030 
00032 class ExecutableCode : boost::noncopyable
00033 {
00034 public:
00035 
00036     ExecutableCode(DisplayObject* t) : _target(t) {}
00037 
00038     virtual void execute() = 0;
00039 
00040     virtual ~ExecutableCode() {}
00041 
00042     virtual void setReachable() const {}
00043 
00045     void markReachableResources() const {
00046         setReachable();
00047         if (_target) _target->setReachable();
00048     }
00049 
00050     DisplayObject* target() const { 
00051         return _target;
00052     }
00053 
00054 private:
00055 
00056     DisplayObject* _target;
00057 };
00058 
00060 class GlobalCode : public ExecutableCode
00061 {
00062 public:
00063 
00064     GlobalCode(const action_buffer& nBuffer, DisplayObject* nTarget)
00065         :
00066         ExecutableCode(nTarget),
00067         buffer(nBuffer)
00068     {}
00069 
00070     virtual void execute() {
00071         if (!target()->unloaded()) {
00072             ActionExec exec(buffer, target()->get_environment());
00073             exec();
00074         }
00075     }
00076 
00077 private:
00078     const action_buffer& buffer;
00079 };
00080 
00082 class EventCode : public ExecutableCode
00083 {
00084 public:
00085 
00086     typedef std::vector<const action_buffer*> BufferList;
00087 
00088     EventCode(DisplayObject* nTarget)
00089         :
00090         ExecutableCode(nTarget)
00091     {}
00092 
00093     EventCode(DisplayObject* nTarget, const BufferList& buffers)
00094         :
00095         ExecutableCode(nTarget),
00096         _buffers(buffers)
00097     {}
00098 
00100     //
00106     void addAction(const action_buffer& buffer) {
00107         // don't push actions for destroyed DisplayObjects, 
00108         // our opcode guard is bogus at the moment.
00109         if (!target()->isDestroyed()) {
00110             _buffers.push_back(&buffer);
00111         }
00112     }
00113 
00114     virtual void execute() {
00115         for (BufferList::iterator it = _buffers.begin(),
00116             itEnd = _buffers.end(); it != itEnd; ++it) {
00117 
00118             // onClipEvents code are guarded by isDestroyed(),
00119             // still might be also guarded by unloaded()
00120             if (target()->isDestroyed()) break;
00121 
00122             ActionExec exec(*(*it), target()->get_environment(), false);
00123             exec();
00124         }
00125     }
00126 
00127 private:
00128     BufferList _buffers;
00129 };
00130 
00132 class QueuedEvent : public ExecutableCode
00133 {
00134 public:
00135 
00136     QueuedEvent(DisplayObject* nTarget, const event_id& id)
00137         :
00138         ExecutableCode(nTarget),
00139         _eventId(id)
00140     {}
00141 
00142     virtual void execute() {
00143         // don't execute any events for destroyed DisplayObject.
00144         if (!target()->isDestroyed()) {
00145             target()->notifyEvent(_eventId);
00146         }
00147     }
00148 
00149 private:
00150     const event_id _eventId;
00151 };
00152 
00154 //
00164 class DelayedFunctionCall : public ExecutableCode
00165 {
00166 public:
00167 
00168     DelayedFunctionCall(DisplayObject* target,
00169             as_object* obj, const ObjectURI& name,
00170             const as_value& arg1, const as_value& arg2)
00171         :
00172         ExecutableCode(target),
00173         _obj(obj),
00174         _name(name),
00175         _arg1(arg1),
00176         _arg2(arg2)
00177     {}
00178 
00179     virtual void execute() {
00180         callMethod(_obj, _name, _arg1, _arg2);
00181     }
00182 
00184     virtual void setReachable() const {
00185         _obj->setReachable();
00186         _arg1.setReachable();
00187         _arg2.setReachable();
00188     }
00189 
00190 private:
00191     as_object* _obj;
00192     ObjectURI _name;
00193     as_value _arg1, _arg2;
00194 };
00195 
00196 
00197 
00198 } // namespace gnash
00199 
00200 #endif // GNASH_EXECUTABLECODE_H