Gnash  0.8.10
as_object.h
Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
00003 //   Free Software Foundation, Inc
00004 // 
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 3 of the License, or
00008 // (at your option) any later version.
00009 // 
00010 // This program 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
00013 // GNU General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019 #ifndef GNASH_AS_OBJECT_H
00020 #define GNASH_AS_OBJECT_H
00021 
00022 #ifdef HAVE_CONFIG_H
00023 #include "gnashconfig.h"
00024 #endif
00025 
00026 #include <map>
00027 #include <vector>
00028 #include <cmath>
00029 #include <utility> 
00030 #include <boost/scoped_ptr.hpp>
00031 #include <boost/noncopyable.hpp>
00032 
00033 #include "GC.h" // for inheritance from GcResource (to complete)
00034 #include "PropertyList.h"
00035 #include "PropFlags.h"
00036 #include "Relay.h"
00037 #include "ObjectURI.h"
00038 
00039 // Forward declarations
00040 namespace gnash {
00041     class as_function;
00042     class MovieClip;
00043     class DisplayObject;
00044     class as_environment;
00045     class VM;
00046     class IOChannel;
00047     class movie_root;
00048     class RunResources;
00049     class Global_as;
00050     class as_value;
00051     class string_table;
00052 }
00053 
00054 namespace gnash {
00055 
00056 
00058 class Trigger
00059 {
00060 public:
00061 
00062     Trigger(const std::string& propname, as_function& trig,
00063             const as_value& customArg)
00064         :
00065         _propname(propname),
00066         _func(&trig),
00067         _customArg(customArg),
00068         _executing(false),
00069         _dead(false)
00070     {}
00071 
00073     //
00083     as_value call(const as_value& oldval, const as_value& newval, 
00084             as_object& this_obj);
00085 
00087     bool dead() const { return _dead; }
00088 
00089     void kill() {
00090         _dead = true;
00091     }
00092 
00093     void setReachable() const;
00094 
00095 private:
00096 
00098     //
00104     std::string _propname;
00105 
00107     as_function* _func;
00108 
00111     as_value _customArg;
00112 
00114     bool _executing;
00115 
00117     //
00121     bool _dead;
00122 
00123 };
00124 
00126 //
00131 //
00133 //
00138 //
00141 //
00143 //
00145 //
00151 //
00154 //
00156 //
00160 class as_object : public GcResource, boost::noncopyable
00161 {
00162 
00163 public:
00164     
00166     //
00170     explicit as_object(const Global_as& global);
00171 
00173     virtual ~as_object() {}
00174 
00176     //
00180     virtual as_value call(const fn_call& fn);
00181 
00183     //
00186     virtual std::string stringValue() const;
00187 
00189     //
00191     static const int DefaultFlags = PropFlags::dontDelete |
00192                                     PropFlags::dontEnum;
00193 
00195     //
00201     Property* findProperty(const ObjectURI& uri, as_object** owner = 0);
00202 
00204     VM& vm() const {
00205         return _vm;
00206     }
00207 
00209     //
00213     //
00215     void dump_members();
00216 
00218     //
00227     virtual bool set_member(const ObjectURI& uri, const as_value& val,
00228         bool ifFound = false);
00229 
00231     //
00235     //
00240     void init_member(const std::string& name, const as_value& val, 
00241         int flags = DefaultFlags);
00242 
00244     //
00252     //
00258     void init_member(const ObjectURI& uri, const as_value& val, 
00259         int flags = DefaultFlags);
00260 
00262     //
00282     void init_property(const std::string& key, as_function& getter,
00283         as_function& setter, int flags = DefaultFlags);
00284         
00285 
00287     //
00300     void init_property(const std::string& key, as_c_function_ptr getter,
00301         as_c_function_ptr setter, int flags = DefaultFlags);
00302 
00304     //
00308     //
00316     void init_property(const ObjectURI& uri, as_function& getter,
00317         as_function& setter, int flags = DefaultFlags);
00318 
00320     //
00332     void init_property(const ObjectURI& uri, as_c_function_ptr getter,
00333         as_c_function_ptr setter, int flags = DefaultFlags);
00334 
00336     //
00341     //
00346     bool init_destructive_property(const ObjectURI& uri, as_function& getter,
00347             int flags = PropFlags::dontEnum);
00348 
00350     //
00355     //
00360     bool init_destructive_property(const ObjectURI& uri, 
00361             as_c_function_ptr getter, int flags = PropFlags::dontEnum);
00362 
00364     //
00369     // 
00372     //
00376     void init_readonly_property(const std::string& key, as_function& getter,
00377             int flags = DefaultFlags);
00378 
00380     //
00392     void init_readonly_property(const std::string& key,
00393             as_c_function_ptr getter, int flags = DefaultFlags);
00394 
00396     //
00405     bool watch(const ObjectURI& uri, as_function& trig, const as_value& cust);
00406 
00408     //
00412     bool unwatch(const ObjectURI& uri);
00413 
00415     //
00417     //
00420     //
00426     virtual bool get_member(const ObjectURI& uri, as_value* val);
00427 
00434     virtual as_object* get_super(const ObjectURI& fname);
00435     as_object* get_super();
00436 
00438     //
00440     //
00449     std::pair<bool, bool> delProperty(const ObjectURI& uri);
00450 
00452     //
00454     //
00458     Property* getOwnProperty(const ObjectURI& uri);
00459 
00461     //
00467     void set_member_flags(const ObjectURI& uri, int setTrue, int setFalse = 0);
00468 
00470     virtual as_function* to_function() { return 0; }
00471 
00473     virtual bool isSuper() const { return false; }
00474 
00476     //
00482     //
00485     void addInterface(as_object* ctor);
00486 
00488     //
00492     //
00496     //
00502     bool instanceOf(as_object* ctor);
00503 
00505     //
00507     //
00511     bool prototypeOf(as_object& instance);
00512 
00514     //
00519     //
00522     void setPropFlags(const as_value& props, int set_false, int set_true);
00523 
00525     //
00527     //
00529     void copyProperties(const as_object& o);
00530 
00532     void clearProperties() {
00533         _members.clear();
00534     }
00535 
00537     //
00541     //
00545     template<typename T>
00546     void visitProperties(PropertyVisitor& visitor) const {
00547         _members.visitValues<T>(visitor);
00548     }
00549 
00551     //
00554     //
00559     //
00562     void visitKeys(KeyVisitor& visitor) const;
00563 
00565     //
00572     void add_property(const std::string& key, as_function& getter,
00573         as_function* setter);
00574 
00576     //
00581     as_object* get_prototype() const;
00582 
00584     //
00587     void set_prototype(const as_value& proto);
00588 
00590     //
00594     //
00599     //
00603     void setRelay(Relay* p) {
00604         if (p) _array = false;
00605         if (_relay) _relay->clean();
00606         _relay.reset(p);
00607     }
00608 
00610     //
00615     //
00619     Relay* relay() const {
00620         return _relay.get();
00621     }
00622 
00624     bool array() const {
00625         return _array;
00626     }
00627 
00629     void setArray(bool array = true) {
00630         _array = array;
00631     }
00632 
00634     //
00637     DisplayObject* displayObject() const {
00638         return _displayObject;
00639     }
00640 
00642     void setDisplayObject(DisplayObject* d) {
00643         _displayObject = d;
00644     }
00645 
00646 protected:
00647 
00649     //
00658     explicit as_object(VM& vm);
00659 
00661     //
00667     virtual void markReachableResources() const;
00668 
00669 private:
00670 
00672     //
00674     //
00682     Property* findUpdatableProperty(const ObjectURI& uri);
00683 
00684     void executeTriggers(Property* prop, const ObjectURI& uri,
00685             const as_value& val);
00686 
00688     template<typename T> class PrototypeRecursor;
00689 
00691     //
00694     DisplayObject* _displayObject;
00695 
00697     //
00703     bool _array;
00704 
00706     //
00709     boost::scoped_ptr<Relay> _relay;
00710 
00712     VM& _vm;
00713 
00715     PropertyList _members;
00716 
00718     //
00721     std::vector<as_object*> _interfaces;
00722 
00723     typedef std::map<ObjectURI, Trigger, ObjectURI::LessThan> TriggerContainer;
00724     boost::scoped_ptr<TriggerContainer> _trigs;
00725 };
00726 
00728 //
00732 //
00734 //
00739 void sendEvent(as_object& o, const as_environment& env, const ObjectURI& name);
00740 
00742 //
00745 //
00747 //
00748 //
00754 inline as_value
00755 getMember(as_object& o, const ObjectURI& uri)
00756 {
00757     as_value ret;
00758     o.get_member(uri, &ret);
00759     return ret;
00760 }
00761 
00763 //
00766 //
00769 //
00775 inline as_value
00776 getOwnProperty(as_object& o, const ObjectURI& uri)
00777 {
00778     Property* p = o.getOwnProperty(uri);
00779     return p ? p->getValue(o) : as_value();
00780 }
00781 
00783 class IsVisible
00784 {
00785 public:
00786     IsVisible(int version) : _version(version) {}
00787     bool operator()(const Property& prop) const {
00788         return visible(prop, _version);
00789     }
00790 private:
00791     const int _version;
00792 };
00793 
00794 class Exists
00795 {
00796 public:
00797     Exists() {}
00798     bool operator()(const Property&) const {
00799         return true;
00800     }
00801 };
00802 
00803 class IsEnumerable
00804 {
00805 public:
00806     IsEnumerable() {}
00807     bool operator()(const Property& p) const {
00808         return !p.getFlags().test<PropFlags::dontEnum>();
00809     }
00810 };
00811 
00813 //
00818 //
00822 std::string getURLEncodedVars(as_object& o);
00823 
00825 //
00831 as_object* getPathElement(as_object& o, const ObjectURI& uri);
00832 
00833 
00835 //
00839 template<typename T>
00840 T*
00841 get(as_object* o)
00842 {
00843     if (!o) return 0;
00844     return dynamic_cast<T*>(o->displayObject());
00845 }
00846 
00848 //
00852 inline bool
00853 hasOwnProperty(as_object& o, const ObjectURI& uri)
00854 {
00855     return (o.getOwnProperty(uri));
00856 }
00857 
00858 as_object* getObjectWithPrototype(Global_as& gl, const ObjectURI& c);
00859 
00861 //
00865 //
00872 template<typename T>
00873 bool
00874 isNativeType(const as_object* obj, T*& relay)
00875 {
00876     if (!obj) return false;
00877     relay = dynamic_cast<T*>(obj->relay());
00878     return relay;
00879 }
00880 
00882 //
00886 typedef std::vector<std::pair<ObjectURI, as_value> > SortedPropertyList;
00887     
00889 //
00892 //
00896 //
00899 //
00902 SortedPropertyList enumerateProperties(as_object& o);
00903 
00905 VM& getVM(const as_object& o);
00906 
00908 movie_root& getRoot(const as_object& o);
00909 
00911 string_table& getStringTable(const as_object& o);
00912 
00914 const RunResources& getRunResources(const as_object& o);
00915 
00917 int getSWFVersion(const as_object& o);
00918 
00920 Global_as& getGlobal(const as_object& o);
00921 
00923 inline bool caseless(const as_object& o) {
00924     return getSWFVersion(o) < 7;
00925 }
00926 
00927 } // namespace gnash
00928 
00929 #endif // GNASH_AS_OBJECT_H