00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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 "string_table.h"
00027 #include "GC.h"
00028 #include "PropertyList.h"
00029 #include "PropFlags.h"
00030 #include "Relay.h"
00031 #include "ObjectURI.h"
00032
00033 #include <map>
00034 #include <vector>
00035 #include <cmath>
00036 #include <utility>
00037 #include <set>
00038 #include <sstream>
00039 #include <boost/scoped_ptr.hpp>
00040 #include <boost/noncopyable.hpp>
00041 #include <deque>
00042
00043
00044 namespace gnash {
00045 class as_function;
00046 class MovieClip;
00047 class DisplayObject;
00048 class as_environment;
00049 class VM;
00050 class IOChannel;
00051 class movie_root;
00052 class RunResources;
00053 class Global_as;
00054 class as_value;
00055 }
00056
00057 namespace gnash {
00058
00059
00061 class AbstractPropertyVisitor {
00062 public:
00063
00065 virtual bool accept(const ObjectURI& uri, const as_value& val) = 0;
00066 virtual ~AbstractPropertyVisitor() {}
00067 };
00068
00070 class Trigger
00071 {
00072 public:
00073
00074 Trigger(const std::string& propname, as_function& trig,
00075 const as_value& customArg)
00076 :
00077 _propname(propname),
00078 _func(&trig),
00079 _customArg(customArg),
00080 _executing(false),
00081 _dead(false)
00082 {}
00083
00085
00095 as_value call(const as_value& oldval, const as_value& newval,
00096 as_object& this_obj);
00097
00099 bool dead() const { return _dead; }
00100
00101 void kill() {
00102 _dead = true;
00103 }
00104
00105 void setReachable() const;
00106
00107 private:
00108
00110
00116 std::string _propname;
00117
00119 as_function* _func;
00120
00123 as_value _customArg;
00124
00126 bool _executing;
00127
00129
00133 bool _dead;
00134
00135 };
00136
00138
00143
00145
00150
00153
00155
00157
00163
00166
00168
00172 class as_object : public GcResource, boost::noncopyable
00173 {
00174
00175 public:
00176
00177 typedef std::pair<std::string, std::string> KeyValuePair;
00178
00180
00184
00187 typedef std::deque<KeyValuePair> SortedPropertyList;
00188
00190
00194 explicit as_object(Global_as& global);
00195
00197
00201 virtual as_value call(const fn_call& fn);
00202
00204
00207 virtual const std::string& stringValue() const;
00208
00210
00212 static const int DefaultFlags = PropFlags::dontDelete |
00213 PropFlags::dontEnum;
00214
00216
00222 Property* findProperty(const ObjectURI& uri, as_object **owner = NULL);
00223
00225 VM& vm() const {
00226 return _vm;
00227 }
00228
00230
00234
00236 void dump_members();
00237
00239
00243
00245 void dump_members(std::map<std::string, as_value>& to);
00246
00248
00257 virtual bool set_member(const ObjectURI& uri, const as_value& val,
00258 bool ifFound = false);
00259
00261
00265
00270 void init_member(const std::string& name, const as_value& val,
00271 int flags = DefaultFlags);
00272
00274
00282
00288 void init_member(const ObjectURI& uri, const as_value& val,
00289 int flags = DefaultFlags);
00290
00292
00312 void init_property(const std::string& key, as_function& getter,
00313 as_function& setter, int flags = DefaultFlags);
00314
00315
00317
00330 void init_property(const std::string& key, as_c_function_ptr getter,
00331 as_c_function_ptr setter, int flags = DefaultFlags);
00332
00334
00338
00346 void init_property(const ObjectURI& uri, as_function& getter,
00347 as_function& setter, int flags = DefaultFlags);
00348
00350
00362 void init_property(const ObjectURI& uri, as_c_function_ptr getter,
00363 as_c_function_ptr setter, int flags = DefaultFlags);
00364
00366
00371
00376 bool init_destructive_property(const ObjectURI& uri, as_function& getter,
00377 int flags = PropFlags::dontEnum);
00378
00380
00385
00390 bool init_destructive_property(const ObjectURI& uri,
00391 as_c_function_ptr getter, int flags = PropFlags::dontEnum);
00392
00394
00399
00402
00406 void init_readonly_property(const std::string& key, as_function& getter,
00407 int flags = DefaultFlags);
00408
00409 void init_readonly_property(const ObjectURI& uri,
00410 as_function& getter, int flags = DefaultFlags);
00411
00413
00425 void init_readonly_property(const std::string& key,
00426 as_c_function_ptr getter, int flags = DefaultFlags);
00427
00428 void init_readonly_property(const ObjectURI& uri,
00429 as_c_function_ptr getter, int flags = DefaultFlags);
00430
00432
00435
00440 void enumeratePropertyKeys(as_environment& env) const;
00441
00443
00452 bool watch(const ObjectURI& uri, as_function& trig, const as_value& cust);
00453
00455
00459 bool unwatch(const ObjectURI& uri);
00460
00462
00465
00471 virtual bool get_member(const ObjectURI& uri, as_value* val);
00472
00474
00480 virtual as_object* get_path_element(string_table::key key);
00481
00488 virtual as_object* get_super(string_table::key fname = 0);
00489
00491
00496
00503 as_value getMember(const ObjectURI& uri);
00504
00506
00508
00519 std::pair<bool, bool> delProperty(const ObjectURI& uri);
00520
00522
00524
00530 Property* getOwnProperty(const ObjectURI& uri);
00531
00533
00539 bool hasOwnProperty(const ObjectURI& uri);
00540
00542
00548 void set_member_flags(const ObjectURI& uri, int setTrue, int setFalse = 0);
00549
00551 virtual as_function* to_function() { return 0; }
00552
00554 virtual bool isSuper() const { return false; }
00555
00557
00563
00566 void addInterface(as_object* ctor);
00567
00569
00573
00577
00583 bool instanceOf(as_object* ctor);
00584
00586
00588
00592 bool prototypeOf(as_object& instance);
00593
00595
00600
00603 void setPropFlags(const as_value& props, int set_false, int set_true);
00604
00605 #ifdef USE_DEBUGGER
00606
00607 PropertyList &get_properties() { return _members; };
00608 #endif
00609
00611
00613
00615 void copyProperties(const as_object& o);
00616
00618 void clearProperties() {
00619 _members.clear();
00620 }
00621
00623
00627
00632 template<typename T>
00633 void visitProperties(AbstractPropertyVisitor& visitor) const {
00634 _members.visitValues<T>(visitor);
00635 }
00636
00638
00645 void add_property(const std::string& key, as_function& getter,
00646 as_function* setter);
00647
00649
00654 as_object* get_prototype() const;
00655
00657
00660 void set_prototype(const as_value& proto);
00661
00663
00667
00672
00676 void setRelay(Relay* p) {
00677 if (p) _array = false;
00678 _relay.reset(p);
00679 }
00680
00682
00687
00691 Relay* relay() const {
00692 return _relay.get();
00693 }
00694
00696 bool array() const {
00697 return _array;
00698 }
00699
00701 void setArray(bool array = true) {
00702 _array = array;
00703 }
00704
00706
00709 DisplayObject* displayObject() const {
00710 return _displayObject;
00711 }
00712
00714 void setDisplayObject(DisplayObject* d) {
00715 _displayObject = d;
00716 }
00717
00718 protected:
00719
00721
00730 explicit as_object(VM& vm);
00731
00732
00734
00741 virtual void markReachableResources() const {
00742 markAsObjectReachable();
00743 }
00744
00746 void markAsObjectReachable() const;
00747
00748 private:
00749
00751
00753
00761 Property* findUpdatableProperty(const ObjectURI& uri);
00762
00763 void executeTriggers(Property* prop, const ObjectURI& uri,
00764 const as_value& val);
00765
00767 template<typename T> class PrototypeRecursor;
00768
00770
00773 DisplayObject* _displayObject;
00774
00776
00782 bool _array;
00783
00785
00788 boost::scoped_ptr<Relay> _relay;
00789
00791 VM& _vm;
00792
00794 PropertyList _members;
00795
00797
00800 std::vector<as_object*> _interfaces;
00801
00802 typedef std::map<ObjectURI, Trigger> TriggerContainer;
00803 boost::scoped_ptr<TriggerContainer> _trigs;
00804 };
00805
00807 class IsVisible
00808 {
00809 public:
00810 IsVisible(int version) : _version(version) {}
00811 bool operator()(const Property& prop) const {
00812 return visible(prop, _version);
00813 }
00814 private:
00815 const int _version;
00816 };
00817
00818 class Exists
00819 {
00820 public:
00821 Exists() {}
00822 bool operator()(const Property&) const {
00823 return true;
00824 }
00825 };
00826
00827 class IsEnumerable
00828 {
00829 public:
00830 IsEnumerable() {}
00831 bool operator()(const Property& p) const {
00832 return !p.getFlags().get_dont_enum();
00833 }
00834 };
00835
00837
00842
00846 void getURLEncodedVars(as_object& o, std::string& data);
00847
00848
00850
00854 template<typename T>
00855 T*
00856 get(as_object* o)
00857 {
00858 if (!o) return 0;
00859 return dynamic_cast<T*>(o->displayObject());
00860 }
00861
00862 as_object* getObjectWithPrototype(Global_as& gl, string_table::key c);
00863
00865
00869
00876 template<typename T>
00877 bool
00878 isNativeType(as_object* obj, T*& relay)
00879 {
00880 if (!obj) return false;
00881 relay = dynamic_cast<T*>(obj->relay());
00882 return relay;
00883 }
00884
00886
00889
00893 void enumerateProperties(as_object& o, as_object::SortedPropertyList& to);
00894
00896 VM& getVM(const as_object& o);
00897
00899 movie_root& getRoot(const as_object& o);
00900
00902 string_table& getStringTable(const as_object& o);
00903
00905 const RunResources& getRunResources(const as_object& o);
00906
00908 int getSWFVersion(const as_object& o);
00909
00911 Global_as& getGlobal(const as_object& o);
00912
00914 inline bool caseless(const as_object& o) {
00915 return getSWFVersion(o) < 7;
00916 }
00917
00918 }
00919
00920 #endif // GNASH_AS_OBJECT_H