Gnash  0.8.11dev
as_object.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 // Free Software Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 #ifndef GNASH_AS_OBJECT_H
20 #define GNASH_AS_OBJECT_H
21 
22 #ifdef HAVE_CONFIG_H
23 #include "gnashconfig.h"
24 #endif
25 
26 #include <map>
27 #include <vector>
28 #include <cmath>
29 #include <utility>
30 #include <boost/scoped_ptr.hpp>
31 #include <boost/noncopyable.hpp>
32 
33 #include "GC.h" // for inheritance from GcResource (to complete)
34 #include "PropertyList.h"
35 #include "PropFlags.h"
36 #include "Relay.h"
37 #include "ObjectURI.h"
38 
39 // Forward declarations
40 namespace gnash {
41  class as_function;
42  class MovieClip;
43  class DisplayObject;
44  class as_environment;
45  class VM;
46  class IOChannel;
47  class movie_root;
48  class RunResources;
49  class Global_as;
50  class as_value;
51  class string_table;
52 }
53 
54 namespace gnash {
55 
56 
58 class Trigger
59 {
60 public:
61 
62  Trigger(const std::string& propname, as_function& trig,
63  const as_value& customArg)
64  :
65  _propname(propname),
66  _func(&trig),
67  _customArg(customArg),
68  _executing(false),
69  _dead(false)
70  {}
71 
73  //
83  as_value call(const as_value& oldval, const as_value& newval,
84  as_object& this_obj);
85 
87  bool dead() const { return _dead; }
88 
89  void kill() {
90  _dead = true;
91  }
92 
93  void setReachable() const;
94 
95 private:
96 
98  //
104  std::string _propname;
105 
107  as_function* _func;
108 
111  as_value _customArg;
112 
114  bool _executing;
115 
117  //
121  bool _dead;
122 
123 };
124 
126 //
131 //
133 //
138 //
141 //
143 //
145 //
151 //
154 //
156 //
160 class as_object : public GcResource, boost::noncopyable
161 {
162 
163 public:
164 
166  //
170  explicit as_object(const Global_as& global);
171 
173  virtual ~as_object() {}
174 
176  //
180  virtual as_value call(const fn_call& fn);
181 
183  //
186  virtual std::string stringValue() const;
187 
189  //
191  static const int DefaultFlags = PropFlags::dontDelete |
193 
195  //
201  Property* findProperty(const ObjectURI& uri, as_object** owner = 0);
202 
204  VM& vm() const {
205  return _vm;
206  }
207 
209  //
213  //
215  void dump_members();
216 
218  //
227  virtual bool set_member(const ObjectURI& uri, const as_value& val,
228  bool ifFound = false);
229 
231  //
235  //
240  void init_member(const std::string& name, const as_value& val,
241  int flags = DefaultFlags);
242 
244  //
252  //
258  void init_member(const ObjectURI& uri, const as_value& val,
259  int flags = DefaultFlags);
260 
262  //
282  void init_property(const std::string& key, as_function& getter,
283  as_function& setter, int flags = DefaultFlags);
284 
285 
287  //
300  void init_property(const std::string& key, as_c_function_ptr getter,
301  as_c_function_ptr setter, int flags = DefaultFlags);
302 
304  //
308  //
316  void init_property(const ObjectURI& uri, as_function& getter,
317  as_function& setter, int flags = DefaultFlags);
318 
320  //
332  void init_property(const ObjectURI& uri, as_c_function_ptr getter,
333  as_c_function_ptr setter, int flags = DefaultFlags);
334 
336  //
341  //
346  bool init_destructive_property(const ObjectURI& uri, as_function& getter,
347  int flags = PropFlags::dontEnum);
348 
350  //
355  //
360  bool init_destructive_property(const ObjectURI& uri,
361  as_c_function_ptr getter, int flags = PropFlags::dontEnum);
362 
364  //
369  //
372  //
376  void init_readonly_property(const std::string& key, as_function& getter,
377  int flags = DefaultFlags);
378 
380  //
392  void init_readonly_property(const std::string& key,
393  as_c_function_ptr getter, int flags = DefaultFlags);
394 
396  //
405  bool watch(const ObjectURI& uri, as_function& trig, const as_value& cust);
406 
408  //
412  bool unwatch(const ObjectURI& uri);
413 
415  //
417  //
420  //
426  virtual bool get_member(const ObjectURI& uri, as_value* val);
427 
434  virtual as_object* get_super(const ObjectURI& fname);
435  as_object* get_super();
436 
438  //
440  //
449  std::pair<bool, bool> delProperty(const ObjectURI& uri);
450 
452  //
454  //
458  Property* getOwnProperty(const ObjectURI& uri);
459 
461  //
467  void set_member_flags(const ObjectURI& uri, int setTrue, int setFalse = 0);
468 
470  virtual as_function* to_function() { return 0; }
471 
473  virtual bool isSuper() const { return false; }
474 
476  //
482  //
485  void addInterface(as_object* ctor);
486 
488  //
492  //
496  //
502  bool instanceOf(as_object* ctor);
503 
505  //
507  //
511  bool prototypeOf(as_object& instance);
512 
514  //
519  //
522  void setPropFlags(const as_value& props, int set_false, int set_true);
523 
525  //
527  //
529  void copyProperties(const as_object& o);
530 
533  _members.clear();
534  }
535 
537  //
541  //
545  template<typename T>
546  void visitProperties(PropertyVisitor& visitor) const {
547  _members.visitValues<T>(visitor);
548  }
549 
551  //
554  //
559  //
562  void visitKeys(KeyVisitor& visitor) const;
563 
565  //
572  void add_property(const std::string& key, as_function& getter,
573  as_function* setter);
574 
576  //
581  as_object* get_prototype() const;
582 
584  //
587  void set_prototype(const as_value& proto);
588 
590  //
594  //
599  //
603  void setRelay(Relay* p) {
604  if (p) _array = false;
605  if (_relay) _relay->clean();
606  _relay.reset(p);
607  }
608 
610  //
615  //
619  Relay* relay() const {
620  return _relay.get();
621  }
622 
624  bool array() const {
625  return _array;
626  }
627 
629  void setArray(bool array = true) {
630  _array = array;
631  }
632 
634  //
638  return _displayObject;
639  }
640 
643  _displayObject = d;
644  }
645 
646 protected:
647 
649  //
658  explicit as_object(VM& vm);
659 
661  //
667  virtual void markReachableResources() const;
668 
669 private:
670 
672  //
674  //
682  Property* findUpdatableProperty(const ObjectURI& uri);
683 
684  void executeTriggers(Property* prop, const ObjectURI& uri,
685  const as_value& val);
686 
688  template<typename T> class PrototypeRecursor;
689 
691  //
694  DisplayObject* _displayObject;
695 
697  //
703  bool _array;
704 
706  //
709  boost::scoped_ptr<Relay> _relay;
710 
712  VM& _vm;
713 
715  PropertyList _members;
716 
718  //
721  std::vector<as_object*> _interfaces;
722 
723  typedef std::map<ObjectURI, Trigger, ObjectURI::LessThan> TriggerContainer;
724  boost::scoped_ptr<TriggerContainer> _trigs;
725 };
726 
728 //
732 //
734 //
739 void sendEvent(as_object& o, const as_environment& env, const ObjectURI& name);
740 
742 //
745 //
747 //
748 //
754 inline as_value
756 {
757  as_value ret;
758  o.get_member(uri, &ret);
759  return ret;
760 }
761 
763 //
766 //
769 //
775 inline as_value
777 {
778  Property* p = o.getOwnProperty(uri);
779  return p ? p->getValue(o) : as_value();
780 }
781 
784 {
785 public:
786  IsVisible(int version) : _version(version) {}
787  bool operator()(const Property& prop) const {
788  return visible(prop, _version);
789  }
790 private:
791  const int _version;
792 };
793 
794 class Exists
795 {
796 public:
797  Exists() {}
798  bool operator()(const Property&) const {
799  return true;
800  }
801 };
802 
804 {
805 public:
807  bool operator()(const Property& p) const {
808  return !p.getFlags().test<PropFlags::dontEnum>();
809  }
810 };
811 
813 //
818 //
822 std::string getURLEncodedVars(as_object& o);
823 
825 //
831 as_object* getPathElement(as_object& o, const ObjectURI& uri);
832 
833 
835 //
839 template<typename T>
840 T*
842 {
843  if (!o) return 0;
844  return dynamic_cast<T*>(o->displayObject());
845 }
846 
848 //
852 inline bool
854 {
855  return (o.getOwnProperty(uri));
856 }
857 
858 as_object* getObjectWithPrototype(Global_as& gl, const ObjectURI& c);
859 
861 //
865 //
872 template<typename T>
873 bool
874 isNativeType(const as_object* obj, T*& relay)
875 {
876  if (!obj) return false;
877  relay = dynamic_cast<T*>(obj->relay());
878  return relay;
879 }
880 
882 //
886 typedef std::vector<std::pair<ObjectURI, as_value> > SortedPropertyList;
887 
889 //
892 //
896 //
899 //
903 
905 VM& getVM(const as_object& o);
906 
908 movie_root& getRoot(const as_object& o);
909 
912 
914 const RunResources& getRunResources(const as_object& o);
915 
917 int getSWFVersion(const as_object& o);
918 
920 Global_as& getGlobal(const as_object& o);
921 
923 inline bool caseless(const as_object& o) {
924  return getSWFVersion(o) < 7;
925 }
926 
927 } // namespace gnash
928 
929 #endif // GNASH_AS_OBJECT_H