Gnash
0.8.10
|
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