use ObjectURI more consistently
[gnash.git] / libcore / as_object.h
blob9edf79fb2db5892bb090ae2b32cb8aec39c4ebc0
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
3 // 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
19 #ifndef GNASH_AS_OBJECT_H
20 #define GNASH_AS_OBJECT_H
22 #ifdef HAVE_CONFIG_H
23 #include "gnashconfig.h"
24 #endif
26 #include <map>
27 #include <vector>
28 #include <cmath>
29 #include <utility>
30 #include <set>
31 #include <sstream>
32 #include <boost/scoped_ptr.hpp>
33 #include <boost/noncopyable.hpp>
35 #include "string_table.h"
36 #include "GC.h" // for inheritance from GcResource (to complete)
37 #include "PropertyList.h"
38 #include "PropFlags.h"
39 #include "Relay.h"
40 #include "ObjectURI.h"
42 // Forward declarations
43 namespace gnash {
44 class as_function;
45 class MovieClip;
46 class DisplayObject;
47 class as_environment;
48 class VM;
49 class IOChannel;
50 class movie_root;
51 class RunResources;
52 class Global_as;
53 class as_value;
56 namespace gnash {
59 /// A trigger that can be associated with a property name
60 class Trigger
62 public:
64 Trigger(const std::string& propname, as_function& trig,
65 const as_value& customArg)
67 _propname(propname),
68 _func(&trig),
69 _customArg(customArg),
70 _executing(false),
71 _dead(false)
74 /// Call the trigger
76 /// @param oldval
77 /// Old value being modified
78 ///
79 /// @param newval
80 /// New value requested
81 ///
82 /// @param this_obj
83 /// Object of which the property is being changed
84 ///
85 as_value call(const as_value& oldval, const as_value& newval,
86 as_object& this_obj);
88 /// True if this Trigger has been disposed of.
89 bool dead() const { return _dead; }
91 void kill() {
92 _dead = true;
95 void setReachable() const;
97 private:
99 /// Name of the property
101 /// By storing a string_table::key we'd save CPU cycles
102 /// while adding/removing triggers and some memory
103 /// on each trigger, but at the cost of looking up
104 /// the string_table on every invocation of the watch...
106 std::string _propname;
108 /// The trigger function
109 as_function* _func;
111 /// A custom argument to pass to the trigger
112 /// after old and new value.
113 as_value _customArg;
115 /// Flag to protect from infinite loops
116 bool _executing;
118 /// Flag to check whether this trigger has been deleted.
120 /// As a trigger can be removed during execution, it shouldn't be
121 /// erased from the container straight away, so this flag prevents
122 /// any execution.
123 bool _dead;
127 /// The base class for all ActionScript objects
129 /// Everything in ActionScript is an object or convertible to an object. This
130 /// class is the base class for all object types and the implementation of the
131 /// ActionScript Object type itself. See asobj/Object.cpp for the ActionScript
132 /// Object interface.
134 /// An AS2 object has 3 principle tasks:
136 /// 1. to store a set of ActionScript properties and to control dynamic access
137 /// to them.
138 /// 2. to store native type information.
139 /// 3. to store 'watches' that report on changes to any member property.
141 /// A fourth but relatively minor task is to store a list of implemented
142 /// interfaces (see as_object::instanceOf()).
144 /// ActionScript has two different levels of Object typing:
146 /// Dynamic Typing
148 /// 1a. Native type information, stored in a Relay and inaccessible
149 /// to ActionScript.
150 /// 1b. Array type information. This is very similar (and possibly identical
151 /// to) Relays.
152 /// 2. Link to a DisplayObject.
154 /// Both these dynamic types can be changed independently at runtime using
155 /// native functions (often, but not always, constructor functions).
157 /// Static Typing
159 /// Functions (as_function), Super objects (as_super) and AS3 Class types
160 /// (as_class) have a static type, that is, they are not convertible to each
161 /// other once created.
162 class as_object : public GcResource, boost::noncopyable
165 public:
167 /// Construct an ActionScript object with no prototype associated.
169 /// @param global A reference to the Global object the new
170 /// object ultimately belongs to. The created object
171 /// uses the resources of the Global object.
172 explicit as_object(const Global_as& global);
174 /// The as_object dtor does nothing special.
175 virtual ~as_object() {}
177 /// Function dispatch
179 /// Various objects can be called, including functions and super objects.
180 /// A normal object has no call functionality, so the default
181 /// implementation throws an ActionTypeError.
182 virtual as_value call(const fn_call& fn);
184 /// Return the string representation for this object
186 /// This is dependent on the VM version and the type of object, function,
187 /// or class.
188 virtual std::string stringValue() const;
190 /// The most common flags for built-in properties.
192 /// Most API properties, including classes and objects, have these flags.
193 static const int DefaultFlags = PropFlags::dontDelete |
194 PropFlags::dontEnum;
196 /// Find a property, scanning the inheritance chain
198 /// @param uri Property identifier.
199 /// @param owner If not null, this is set to the object which contained
200 /// an inherited property.
201 /// @returns A property if found and visible, NULL if not found or
202 /// not visible in current VM version
203 Property* findProperty(const ObjectURI& uri, as_object** owner = 0);
205 /// Return a reference to this as_object's global object.
206 VM& vm() const {
207 return _vm;
210 /// Dump all properties using log_debug
212 /// Note that it is very likely that this will result in changes to the
213 /// object, as accessing getter/setters or destructive properties can
214 /// modify properties.
216 /// Only use this function for temporary debugging!
217 void dump_members();
219 /// Set a member value
221 /// @param uri Property identifier.
222 /// @param val Value to assign to the named property.
223 /// @param ifFound If true, don't create a new member, but rather only
224 /// update an existing one.
225 /// @return true if the given member existed, false otherwise.
226 /// NOTE: the return doesn't tell if the member exists
227 /// after the call, as watch triggers might have deleted
228 /// it after setting.
229 virtual bool set_member(const ObjectURI& uri, const as_value& val,
230 bool ifFound = false);
232 /// Initialize a member value by string
234 /// This is just a wrapper around the other init_member method
235 /// used as a trampoline to avoid changing all classes to
236 /// use string_table::key directly.
238 /// @param name Name of the member.
239 /// @param val Value to assign to the member.
240 /// @param flags Flags for the new member. By default dontDelete
241 /// and dontEnum.
242 void init_member(const std::string& name, const as_value& val,
243 int flags = DefaultFlags);
245 /// Initialize a member value by key
247 /// This method has to be used by built-in classes initialization
248 /// (VM initialization in general) as will avoid to scan the
249 /// inheritance chain.
251 /// By default, members initialized by calling this function will
252 /// be protected from deletion and not shown in enumeration.
253 /// These flags can be explicitly set using the third argument.
255 /// @param uri Property identifier.
256 /// @param val Value to assign to the member.
258 /// @param flags Flags for the new member. By default dontDelete
259 /// and dontEnum.
260 void init_member(const ObjectURI& uri, const as_value& val,
261 int flags = DefaultFlags);
263 /// Initialize a getter/setter property by name
265 /// This is just a wrapper around the other init_property method
266 /// used as a trampoline to avoid changing all classes to
267 /// use string_table::key directly.
269 /// @param key
270 /// Name of the property.
271 /// Will be converted to lowercase if VM is initialized for SWF6 or lower.
273 /// @param getter
274 /// A function to invoke when this property value is requested.
275 /// add_ref will be called on the function.
277 /// @param setter
278 /// A function to invoke when setting this property's value.
279 /// add_ref will be called on the function.
281 /// @param flags
282 /// Flags for the new member. By default dontDelete and dontEnum.
283 /// See PropFlags::Flags.
284 void init_property(const std::string& key, as_function& getter,
285 as_function& setter, int flags = DefaultFlags);
288 /// Initialize a getter/setter property by name
290 /// This is just a wrapper around the other init_property method
291 /// used as a trampoline to avoid changing all classes to
292 /// use string_table::key directly.
294 /// @param key Name of the property. Will be converted to lowercase
295 /// if VM is initialized for SWF6 or lower.
296 /// @param getter A function to invoke when this property value is
297 /// requested.
298 /// @param setter A function to invoke when setting this property's
299 /// value.
300 /// @param flags Flags for the new member. By default dontDelete and
301 /// dontEnum. See PropFlags::Flags.
302 void init_property(const std::string& key, as_c_function_ptr getter,
303 as_c_function_ptr setter, int flags = DefaultFlags);
305 /// Initialize a getter/setter property by key
307 /// This method has to be used by built-in classes initialization
308 /// (VM initialization in general) as will avoid to scan the
309 /// inheritance chain.
311 /// @param uri Property identifier.
312 /// @param getter A function to invoke when this property value is
313 /// requested.
314 /// @param setter A function to invoke when this property value is
315 /// set.
316 /// @param flags Flags for the new member. By default dontEnum and
317 /// dontDelete.
318 void init_property(const ObjectURI& uri, as_function& getter,
319 as_function& setter, int flags = DefaultFlags);
321 /// Initialize a getter/setter property by key
323 /// This method has to be used by built-in classes initialization
324 /// (VM initialization in general) as will avoid to scan the
325 /// inheritance chain.
327 /// @param uri Property identifier.
328 /// @param getter A function to invoke when this property value is
329 /// requested.
330 /// @param setter A function to invoke when this property value is
331 /// set.
332 /// @param flags Flags for the new member. By default dontEnum and
333 /// dontDelete.
334 void init_property(const ObjectURI& uri, as_c_function_ptr getter,
335 as_c_function_ptr setter, int flags = DefaultFlags);
337 /// Initialize a destructive getter property
339 /// A destructive getter can be used as a place holder for the real
340 /// value of a property. As soon as getValue is invoked on the getter,
341 /// it destroys itself after setting its property to the return value of
342 /// getValue.
344 /// @param uri Property identifier.
345 /// @param getter A function to invoke when this property value is
346 /// requested.
347 /// @param flags Flags for the new member. By default dontEnum.
348 bool init_destructive_property(const ObjectURI& uri, as_function& getter,
349 int flags = PropFlags::dontEnum);
351 /// Initialize a destructive getter property
353 /// A destructive getter can be used as a place holder for the real
354 /// value of a property. As soon as getValue is invoked on the getter,
355 /// it destroys itself after setting its property to the return value of
356 /// getValue.
358 /// @param uri Property identifier.
359 /// @param getter A function to invoke when this property value is
360 /// requested.
361 /// @param flags Flags for the new member. By default dontEnum.
362 bool init_destructive_property(const ObjectURI& uri,
363 as_c_function_ptr getter, int flags = PropFlags::dontEnum);
365 /// Use this method for read-only properties.
367 /// This method achieves the same as the above init_property method.
368 /// Additionally, it sets the property as read-only so that a default
369 /// handler will be triggered when ActionScript attempts to set the
370 /// property.
372 /// The arguments are the same as the above init_property arguments,
373 /// although the setter argument is omitted.
375 /// @param key Property name id
376 /// @param getter The getter function
377 /// @param flags Property flags
378 void init_readonly_property(const std::string& key, as_function& getter,
379 int flags = DefaultFlags);
381 /// Use this method for read-only properties.
383 /// This method achieves the same as the above init_property method.
384 /// Additionally, it sets the property as read-only so that a default
385 /// handler will be triggered when ActionScript attempts to set the
386 /// property.
387 ///
388 /// The arguments are the same as the above init_property arguments,
389 /// although the setter argument is omitted.
391 /// @param key Property name id
392 /// @param getter The getter function
393 /// @param flags Property flags
394 void init_readonly_property(const std::string& key,
395 as_c_function_ptr getter, int flags = DefaultFlags);
397 /// Add a watch trigger, overriding any other defined for same name.
399 /// @param uri property identifier
400 /// @param trig A function to invoke when this property value is
401 /// assigned to. The function will be called with old
402 /// val, new val and the custom value below. Its
403 /// return code will be used to set actual value
404 /// @param cust Custom value to always pass to the trigger as third arg
405 /// @return true if the trigger was successfully added, false
406 /// otherwise.
407 bool watch(const ObjectURI& uri, as_function& trig, const as_value& cust);
409 /// Remove a watch trigger.
411 /// @param uri Property identifier.
412 /// @return true if the trigger was successfully removed, false
413 /// otherwise (no such trigger exists).
414 bool unwatch(const ObjectURI& uri);
416 /// Get a property by name if it exists.
418 /// NOTE: accessing a getter/setter property may modify the object.
420 /// See getMember() for a property accessor that corresponds to
421 /// ActionScript behaviour.
423 /// @param uri Property identifier.
424 /// @param val Variable to assign an existing value to.
425 /// Will be untouched if no property with the given name
426 /// was found.
427 /// @return true if the named property was found, false otherwise.
428 virtual bool get_member(const ObjectURI& uri, as_value* val);
430 /// Get the super object of this object.
432 /// The super should be __proto__ if this is a prototype object
433 /// itself, or __proto__.__proto__ if this is not a prototype
434 /// object. This is only conceptual however, and may be more
435 /// convoluted to obtain the actual super.
436 virtual as_object* get_super(const ObjectURI& fname);
437 as_object* get_super();
439 /// Delete a property of this object, unless protected from deletion.
441 /// This function does *not* recurse in this object's prototype.
443 /// @param uri Property identifier.
444 /// @return a pair of boolean values expressing whether the property
445 /// was found (first) and whether it was deleted (second).
446 /// Of course a pair(false, true) would be invalid (deleted
447 /// a non-found property!). Valid returns are:
448 /// - (false, false) : property not found
449 /// - (true, false) : property protected from deletion
450 /// - (true, true) : property successfully deleted
451 std::pair<bool, bool> delProperty(const ObjectURI& uri);
453 /// Get this object's own named property, if existing.
455 /// This function does *not* recurse in this object's prototype.
457 /// @param uri Property identifier.
458 /// @return A Property pointer, or NULL if this object doesn't
459 /// contain the named property.
460 Property* getOwnProperty(const ObjectURI& uri);
462 /// Set member flags (probably used by ASSetPropFlags)
464 /// @param name Name of the property. Must be all lowercase
465 /// if the current VM is initialized for a target
466 /// up to SWF6.
467 /// @param setTrue The set of flags to set
468 /// @param setFalse The set of flags to clear
469 void set_member_flags(const ObjectURI& uri, int setTrue, int setFalse = 0);
471 /// Cast to a as_function, or return NULL
472 virtual as_function* to_function() { return 0; }
474 /// Return true if this is a 'super' object
475 virtual bool isSuper() const { return false; }
477 /// Add an interface to the list of interfaces.
479 /// This is used by the action "implements". This opcode is a compile-time
480 /// promise that a class will implement all the methods of an
481 /// otherwise unrelated interface class. The only use in AVM1 is to
482 /// allow instanceOf to return true when a class implements another
483 /// class.
485 /// @param ctor An as_object to specify as an interface implemented
486 /// by this object.
487 void addInterface(as_object* ctor);
489 /// Check whether this object is an instance of the given constructor
491 /// An object is an instance of a constructor if constructor.prototype is
492 /// found anywhere in the object's prototype chain (e.g. if
493 /// object.__proto__ == constructor.prototype).
495 /// It is also an instance of a constructor if the constructor is
496 /// listed in the object's interfaces (this is a compile-time promise
497 /// and has no runtime effects other than for instanceOf).
499 /// @param ctor The as_object to compare this object to. For more
500 /// ActionScript-like syntax it can be any object
501 /// or null.
502 /// @return true if this object is an instance of ctor. The return
503 /// is always false if ctor is null.
504 bool instanceOf(as_object* ctor);
506 /// Check whether this object is in another object's inheritance chain.
508 /// This is roughly the inverse of instanceOf().
510 /// @param instance The instance object to check for inheritance from
511 /// this object.
512 /// @return true if instance inherits from this object.
513 bool prototypeOf(as_object& instance);
515 /// Set property flags
517 /// @param props A comma-delimited list of property names as a string,
518 /// a NULL value. This is in fact a string, which should
519 /// be split on the ',' to an array then processed.
520 /// TODO: this would be much better as a free function.
522 /// @param set_false A mask of flags to set to false.
523 /// @param set_true A mask of flags to set to true.
524 void setPropFlags(const as_value& props, int set_false, int set_true);
526 #ifdef USE_DEBUGGER
527 /// Get the properties of this object
528 PropertyList &get_properties() { return _members; };
529 #endif
531 /// Copy properties from the given object
533 /// NOTE: the __proto__ member will NOT be copied.
535 /// @param o The object to copy properties from.
536 void copyProperties(const as_object& o);
538 /// Drop all properties from this object
539 void clearProperties() {
540 _members.clear();
543 /// Visit the properties of this object by key/as_value pairs
545 /// The method will invoke the given visitor method with the identifier
546 /// and value of the property. Note that this access values, which may
547 /// change the object.
549 /// @param visitor The visitor function. Will be invoked for each property
550 /// of this object with an ObjectURI as first argument and
551 /// a const as_value as second argument.
552 template<typename T>
553 void visitProperties(PropertyVisitor& visitor) const {
554 _members.visitValues<T>(visitor);
557 /// Visit all visible property identifiers.
559 /// NB: this function does not access the property values, so callers
560 /// can be certain no values will be changed.
562 /// The enumeration recurses through the prototype chain. This
563 /// implementation will keep track of visited object to avoid infinite
564 /// loops in the prototype chain. NOTE: the MM player just chokes in
565 /// this case.
567 /// @param visitor The visitor function. Will be invoked for each property
568 /// of this object with an ObjectURI as the only argument.
569 void visitKeys(KeyVisitor& visitor) const;
571 /// Add a getter/setter property if no member already has that name.
573 /// @param key Property identifier.
574 /// @param getter A function to invoke when this property value
575 /// is requested.
576 /// @param setter A function to invoke when setting this property's
577 /// value. By passing null, the property will have no
578 /// setter. This is valid.
579 void add_property(const std::string& key, as_function& getter,
580 as_function* setter);
582 /// Return this object's __proto__ member.
584 /// The __proto__ member is the exported interface (prototype)
585 /// of the class this object is an instance of.
587 /// NOTE: can return NULL (and it is expected to do for Object.prototype)
588 as_object* get_prototype() const;
590 /// Set this object's __proto__ member
592 /// This does more or less what set_member("__proto__") does, but without
593 /// the lookup process.
594 void set_prototype(const as_value& proto);
596 /// Set the as_object's Relay object.
598 /// This is a pointer to a native object that contains special type
599 /// characteristics. Setting the Relay object allows native functions
600 /// to get or set non-ActionScript properties.
602 /// This function should only be used in native functions such as
603 /// constructors and special creation functions like
604 /// MovieClip.createTextField(). As Relay objects are not available to
605 /// ActionScript, this should never appear in built-in functions.
607 /// This function also removes Array typing from an object when a Relay
608 /// is assigned. There are tests verifying this behaviour in
609 /// actionscript.all and the swfdec testsuite.
610 void setRelay(Relay* p) {
611 if (p) _array = false;
612 _relay.reset(p);
615 /// Access the as_object's Relay object.
617 /// The Relay object is a polymorphic object containing native type
618 /// characteristics. It is rarely useful to use this function directly.
619 /// Instead use the convenience functions ensure<>() and
620 /// isNativeType() to access the Relay object.
622 /// Relay objects are not available to ActionScript, so this object
623 /// should not be used in built-in functions (that is, functions
624 /// implemented in ActionScript).
625 Relay* relay() const {
626 return _relay.get();
629 /// Return true if this object should be treated as an array.
630 bool array() const {
631 return _array;
634 /// Set whether this object should be treated as an array.
635 void setArray(bool array = true) {
636 _array = array;
639 /// Return the DisplayObject associated with this object.
641 /// @return A DisplayObject if this is as_object is associated with
642 /// one, otherwise 0.
643 DisplayObject* displayObject() const {
644 return _displayObject;
647 /// Set the DisplayObject associated with this as_object.
648 void setDisplayObject(DisplayObject* d) {
649 _displayObject = d;
652 protected:
654 /// Construct an as_object associated with a VM.
656 /// This constructor is intended for subclasses. Although they could call
657 /// the public constructor that accepts a Global_as, this could imply
658 /// that that constructor can access members of the passed Global_as
659 /// other than getVM(), which might not be available because the Global_as
660 /// will not be fully constructed yet. While that is currently not the
661 /// case, using this constructor eliminates this potential initialization
662 /// order problem.
663 /// @param vm The VM to associate the newly created as_object with.
664 explicit as_object(VM& vm);
666 /// Mark all reachable resources, override from GcResource.
668 /// The default implementation marks all properties
670 /// If a derived class provides access to more GC-managed
671 /// resources, it should override this function and call
672 /// this function directly as the last step.
673 virtual void markReachableResources() const;
675 private:
677 /// Find an existing property for update
679 /// Scans the inheritance chain only for getter/setters or statics.
681 /// NOTE: updatable here doesn't mean the property isn't protected
682 /// from update but only that a set_member will NOT create a new
683 /// property (either completely new or as an override).
685 /// @returns a property if found, NULL if not found
686 /// or not visible in current VM version
688 Property* findUpdatableProperty(const ObjectURI& uri);
690 void executeTriggers(Property* prop, const ObjectURI& uri,
691 const as_value& val);
693 /// A utility class for processing this as_object's inheritance chain
694 template<typename T> class PrototypeRecursor;
696 /// DisplayObjects have properties not in the AS inheritance chain
698 /// These magic properties are invoked in get_member only if the
699 /// object is a DisplayObject
700 DisplayObject* _displayObject;
702 /// An array is a special type of object.
704 /// Like DisplayObjects, Arrays handle property setting differently. We
705 /// use an extra flag to avoid checking Relay type on every property
706 /// set, but tests show that the Array constructor removes the Relay. It
707 /// would be possible to implement using a Relay, but as an Array stores
708 /// no extra native data, it's not clear what the point is.
709 bool _array;
711 /// The polymorphic Relay object for native types.
713 /// This is owned by the as_object and destroyed when the as_object's
714 /// destructor is called.
715 boost::scoped_ptr<Relay> _relay;
717 /// The VM containing this object.
718 VM& _vm;
720 /// Properties of this as_object
721 PropertyList _members;
723 /// The constructors of the objects implemented by this as_object.
725 /// There is no need to use a complex container as the list of
726 /// interfaces is generally small and the opcode rarely used anyway.
727 std::vector<as_object*> _interfaces;
729 typedef std::map<ObjectURI, Trigger, ObjectURI::LessThan> TriggerContainer;
730 boost::scoped_ptr<TriggerContainer> _trigs;
733 /// Send a system event
735 /// This is used for broadcasting system events. The prototype search is
736 /// carried out, but there is no call to __resolve and triggers
737 /// are not processed.
739 /// The function is called with no arguments.
741 /// @param o The object to send the event to.
742 /// @param env The environment to use, generally provided by the calling
743 /// DisplayObject
744 /// @param name The name of the function to call.
745 void sendEvent(as_object& o, const as_environment& env, const ObjectURI& name);
747 /// Get a member of an object using AS lookup rules
749 /// This is a wrapper round as_object::get_member that returns undefined if
750 /// the member is not found.
752 /// Note: this is the only full lookup process available in ActionScript code.
755 /// @param uri Property identifier.
756 /// @param o The object whose member is required.
757 /// @return Value of the member (possibly undefined),
758 /// or undefined if not found. Use get_member if you
759 /// need to know whether it was found or not.
760 inline as_value
761 getMember(as_object& o, const ObjectURI& uri)
763 as_value ret;
764 o.get_member(uri, &ret);
765 return ret;
768 /// Get an own member of an object.
770 /// This is a wrapper round as_object::getOwnProperty that returns undefined if
771 /// the member is not found.
773 /// Note: this requires two steps in ActionScript (hasOwnProperty + lookup), so
774 /// is probably only for use in native functions.
776 /// @param uri Property identifier.
777 /// @param o The object whose own member is required.
778 /// @return Value of the member (possibly undefined),
779 /// or undefined if not found. Use get_member if you
780 /// need to know whether it was found or not.
781 inline as_value
782 getOwnProperty(as_object& o, const ObjectURI& uri)
784 Property* p = o.getOwnProperty(uri);
785 return p ? p->getValue(o) : as_value();
788 /// Function objects for visiting properties.
789 class IsVisible
791 public:
792 IsVisible(int version) : _version(version) {}
793 bool operator()(const Property& prop) const {
794 return visible(prop, _version);
796 private:
797 const int _version;
800 class Exists
802 public:
803 Exists() {}
804 bool operator()(const Property&) const {
805 return true;
809 class IsEnumerable
811 public:
812 IsEnumerable() {}
813 bool operator()(const Property& p) const {
814 return !p.getFlags().test<PropFlags::dontEnum>();
818 /// Get url-encoded variables
820 /// This method will be used for loadVariables and loadMovie
821 /// calls, to encode variables for sending over a network.
822 /// Variables starting with a dollar sign will be skipped,
823 /// as non-enumerable ones.
825 /// @param o The object whose properties should be encoded.
826 /// @return the url-encoded variables string without any leading
827 /// delimiter.
828 std::string getURLEncodedVars(as_object& o);
830 /// Resolve the given relative path component
832 /// Path components are only objects, if the given string
833 /// points to a non-object member, NULL is returned.
835 /// Main use if for getvariable and settarget resolution,
836 /// currently implemented in as_environment.
837 as_object* getPathElement(as_object& o, const ObjectURI& uri);
840 /// Extract the DisplayObject attached to an object
842 /// @return 0 if no DisplayObject is attached, or if it is not the
843 /// requested type
844 /// @param o The object to check.
845 template<typename T>
847 get(as_object* o)
849 if (!o) return 0;
850 return dynamic_cast<T*>(o->displayObject());
853 /// Return true if this object has the named property
855 /// @param o The object whose property should be searched for.
856 /// @param uri Property identifier.
857 /// @return true if the object has the property, false otherwise.
858 inline bool
859 hasOwnProperty(as_object& o, const ObjectURI& uri)
861 return (o.getOwnProperty(uri));
864 as_object* getObjectWithPrototype(Global_as& gl, const ObjectURI& c);
866 /// Check whether the object is an instance of a known type.
868 /// This is used to check the type of certain objects when it can't be
869 /// done through ActionScript and properties. Examples include conversion
870 /// of Date and String objects.
872 /// @tparam T The expected native type
873 /// @param obj The object whose type should be tested
874 /// @param relay This points to the native type information if the object
875 /// is of the expected type
876 /// @return If the object is of the expected type, true; otherwise
877 /// false.
878 template<typename T>
879 bool
880 isNativeType(as_object* obj, T*& relay)
882 if (!obj) return false;
883 relay = dynamic_cast<T*>(obj->relay());
884 return relay;
887 /// This is used to hold an intermediate copy of an as_object's properties.
889 /// AS enumerates in reverse order of creation because these values are
890 /// pushed to the stack. The first value to be popped is then the oldest
891 /// property.
892 typedef std::vector<std::pair<ObjectURI, as_value> > SortedPropertyList;
894 /// Enumerate all non-hidden properties to the passed container
896 /// NB: it is likely that this call will change the object, as accessing
897 /// property values may call getter-setters.
899 /// The enumeration recurses through the prototype chain. This implementation
900 /// will keep track of visited object to avoid infinite loops in the
901 /// prototype chain. NOTE: the Adobe player just chokes in this case.
903 /// Note that the last element of the returned container is the oldest
904 /// property, so iterate in reverse to mimic AS behaviour.
906 /// @param o The object whose properties should be enumerated.
907 /// @return A list of properties in reverse creation order.
908 SortedPropertyList enumerateProperties(as_object& o);
910 /// Get the VM from an as_object.
911 VM& getVM(const as_object& o);
913 /// Get the movie_root from an as_object.
914 movie_root& getRoot(const as_object& o);
916 /// Get the string_table from an as_object.
917 string_table& getStringTable(const as_object& o);
919 /// Get the RunResources from an as_object.
920 const RunResources& getRunResources(const as_object& o);
922 /// Get the executing VM version from an as_object.
923 int getSWFVersion(const as_object& o);
925 /// Get the Global object from an as_object.
926 Global_as& getGlobal(const as_object& o);
928 /// Return whether property matching is caseless
929 inline bool caseless(const as_object& o) {
930 return getSWFVersion(o) < 7;
933 } // namespace gnash
935 #endif // GNASH_AS_OBJECT_H