Gnash  0.8.11dev
Property.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 
20 #ifndef GNASH_PROPERTY_H
21 #define GNASH_PROPERTY_H
22 
23 #include <boost/variant.hpp>
24 #include <cassert>
25 #include <boost/bind.hpp>
26 #include <typeinfo>
27 
28 #include "PropFlags.h"
29 #include "as_value.h"
30 #include "ObjectURI.h"
31 #include "dsodefs.h" // for DSOTEXPORT
32 
33 namespace gnash {
34  typedef as_value (*as_c_function_ptr)(const fn_call& fn);
35  class as_function;
36 }
37 
38 namespace gnash {
39 
41 //
45 {
46  class NativeGetterSetter;
47 
48  // The following helper structs define common operations on the
49  // Two types of GetterSetter. Some operations are applicable only to
50  // one type.
51 
53  //
57  template<typename Arg, typename S>
58  struct GetSetVisitor : boost::static_visitor<typename S::result_type>
59  {
60  GetSetVisitor(const Arg& arg) : _arg(arg) {}
61  template<typename T> typename S::result_type operator()(T& t) const {
62  return S()(t, _arg);
63  }
64  private:
65  const Arg& _arg;
66  };
67 
69  struct Set
70  {
71  typedef void result_type;
72  template<typename T, typename Arg>
73  result_type operator()(T& t, Arg& a) const {
74  t.set(a);
75  }
76  };
77 
79  struct Get
80  {
81  typedef as_value result_type;
82  template<typename T, typename Arg>
83  result_type operator()(T& t, Arg& a) const {
84  return t.get(a);
85  }
86  };
87 
89  //
91  struct SetUnderlying : boost::static_visitor<>
92  {
93  template<typename T>
94  result_type operator()(T& gs, const as_value& val) const {
95  gs.setUnderlying(val);
96  }
97  result_type operator()(NativeGetterSetter&, const as_value&) const {}
98  };
99 
101  //
103  struct GetUnderlying : boost::static_visitor<as_value>
104  {
105  template<typename T>
106  result_type operator()(const T& gs) const {
107  return gs.getUnderlying();
108  }
109  result_type operator()(const NativeGetterSetter&) const {
110  return result_type();
111  }
112  };
113 
115  struct MarkReachable : boost::static_visitor<>
116  {
117  template<typename T>
118  result_type operator()(const T& gs) const {
119  gs.markReachableResources();
120  }
121  };
122 
123 public:
124 
127  :
128  _getset(UserDefinedGetterSetter(getter, setter))
129  {}
130 
133  :
134  _getset(NativeGetterSetter(getter, setter))
135  {}
136 
138  as_value get(fn_call& fn) const {
139  GetSetVisitor<const fn_call, Get> s(fn);
140  return boost::apply_visitor(s, _getset);
141  }
142 
144  void set(const fn_call& fn) {
145  GetSetVisitor<fn_call, Set> s(fn);
146  boost::apply_visitor(s, _getset);
147  }
148 
150  void setCache(const as_value& v) {
151  boost::apply_visitor(boost::bind(SetUnderlying(), _1, v), _getset);
152  }
153 
155  as_value getCache() const {
156  return boost::apply_visitor(GetUnderlying(), _getset);
157  }
158 
159  void markReachableResources() const {
160  boost::apply_visitor(MarkReachable(), _getset);
161  }
162 
163 private:
164 
166  class UserDefinedGetterSetter
167  {
168  public:
169 
170  UserDefinedGetterSetter(as_function* get, as_function* set)
171  :
172  _getter(get),
173  _setter(set),
174  _underlyingValue(),
175  _beingAccessed(false)
176  {}
177 
179  as_value get(const fn_call& fn) const;
180 
182  void set(const fn_call& fn);
183 
185  const as_value& getUnderlying() const { return _underlyingValue; }
186 
188  void setUnderlying(const as_value& v) { _underlyingValue = v; }
189 
190  void markReachableResources() const;
191 
192  private:
193 
197  //
200  class ScopedLock : boost::noncopyable
201  {
202  public:
203 
204  explicit ScopedLock(const UserDefinedGetterSetter& na)
205  :
206  _a(na),
207  _obtainedLock(_a._beingAccessed ? false : true)
208  {
209  // If we didn't obtain the lock it would be true anyway,
210  // but it's probably polite to avoid touching it.
211  if (_obtainedLock) _a._beingAccessed = true;
212  }
213 
214  ~ScopedLock() { if ( _obtainedLock) _a._beingAccessed = false; }
215 
217  //
222  bool obtainedLock() const { return _obtainedLock; }
223 
224  private:
225 
226  const UserDefinedGetterSetter& _a;
227  bool _obtainedLock;
228 
229  };
230 
231  as_function* _getter;
232  as_function* _setter;
233  as_value _underlyingValue;
234  mutable bool _beingAccessed;
235  };
236 
238  class NativeGetterSetter
239  {
240  public:
241 
242  NativeGetterSetter(as_c_function_ptr get, as_c_function_ptr set)
243  :
244  _getter(get), _setter(set) {}
245 
247  as_value get(const fn_call& fn) const {
248  return _getter(fn);
249  }
250 
252  void set(const fn_call& fn) {
253  _setter(fn);
254  }
255 
257  void markReachableResources() const {}
258 
259  private:
260  as_c_function_ptr _getter;
261  as_c_function_ptr _setter;
262  };
263 
264  boost::variant<UserDefinedGetterSetter, NativeGetterSetter> _getset;
265 
266 };
267 
269 //
271 //
275 class Property
276 {
277 
279  struct SetReachable : boost::static_visitor<>
280  {
281  result_type operator()(const as_value& val) const {
282  val.setReachable();
283  }
284  result_type operator()(const GetterSetter& gs) const {
285  return gs.markReachableResources();
286  }
287  };
288 
289 public:
290 
291  Property(const ObjectURI& uri, const as_value& value,
292  const PropFlags& flags)
293  :
294  _bound(value),
295  _uri(uri),
296  _flags(flags),
297  _destructive(false)
298  {}
299 
301  as_function* getter, as_function* setter,
302  const PropFlags& flags, bool destroy = false)
303  :
304  _bound(GetterSetter(getter, setter)),
305  _uri(uri),
306  _flags(flags),
307  _destructive(destroy)
308  {}
309 
311  as_c_function_ptr setter, const PropFlags& flags,
312  bool destroy = false)
313  :
314  _bound(GetterSetter(getter, setter)),
315  _uri(uri),
316  _flags(flags),
317  _destructive(destroy)
318  {}
319 
322  :
323  _bound(p._bound),
324  _uri(p._uri),
325  _flags(p._flags),
326  _destructive(p._destructive)
327  {}
328 
330  const PropFlags& getFlags() const { return _flags; }
331 
333  void setFlags(const PropFlags& flags) const {
334  _flags = flags;
335  }
336 
338  //
346  DSOTEXPORT as_value getValue(const as_object& this_ptr) const;
347 
349  //
355  as_value getCache() const;
356 
358  //
364  void setCache(const as_value& v);
365 
367  //
382  bool setValue(as_object& this_ptr, const as_value &value) const;
383 
385  bool isGetterSetter() const {
386  return _bound.type() == typeid(GetterSetter);
387  }
388 
390  void clearVisible(int swfVersion) { _flags.clear_visible(swfVersion); }
391 
393  const ObjectURI& uri() const {
394  return _uri;
395  }
396 
398  void setReachable() const {
399  return boost::apply_visitor(SetReachable(), _bound);
400  }
401 
402 private:
403 
404  // Store the various types of things that can be held.
405  typedef boost::variant<as_value, GetterSetter> BoundType;
406 
408  mutable BoundType _bound;
409 
411  ObjectURI _uri;
412 
414  mutable PropFlags _flags;
415 
416  // If true, as soon as getValue has been invoked once, the
417  // returned value becomes a fixed return (though it can be
418  // overwritten if not readOnly)
419  mutable bool _destructive;
420 
421 };
422 
424 inline bool
425 readOnly(const Property& prop) {
426  return prop.getFlags().test<PropFlags::readOnly>();
427 }
428 
430 inline bool
431 visible(const Property& prop, int version) {
432  return prop.getFlags().get_visible(version);
433 }
434 
435 } // namespace gnash
436 
437 #endif // GNASH_PROPERTY_H
Definition: GnashKey.h:147
void setCache(const as_value &v)
Set internal cached value of this property.
Definition: Property.cpp:172
Holder for getter/setter functions.
Definition: Property.h:44
SWFStream & s
Definition: DefineBitsTag.cpp:73
Property(const ObjectURI &uri, as_function *getter, as_function *setter, const PropFlags &flags, bool destroy=false)
Definition: Property.h:300
ActionScript value type.
Definition: as_value.h:95
Property(const ObjectURI &uri, const as_value &value, const PropFlags &flags)
Definition: Property.h:291
as_value(* as_c_function_ptr)(const fn_call &fn)
Definition: Property.h:34
An abstract property.
Definition: Property.h:275
DSOTEXPORT as_value getValue(const as_object &this_ptr) const
Get value of this property.
Definition: Property.cpp:98
Definition: GnashKey.h:131
GetterSetter(as_c_function_ptr getter, as_c_function_ptr setter)
Construct a native getter-setter.
Definition: Property.h:132
Flags defining the level of protection of a member.
Definition: PropFlags.h:28
Anonymous namespace for callbacks, local functions, event handlers etc.
Definition: dbus_ext.cpp:40
as_value getCache() const
Get the cache value (for user-defined getter-setters)
Definition: Property.h:155
The base class for all ActionScript objects.
Definition: as_object.h:161
bool isGetterSetter() const
Is this a getter/setter property?
Definition: Property.h:385
void setCache(const as_value &v)
Set the cache value (for user-defined getter-setters)
Definition: Property.h:150
bool get_visible(int swfVersion) const
Get version-based visibility.
Definition: PropFlags.h:99
A URI for describing as_objects.
Definition: ObjectURI.h:44
as_value get(fn_call &fn) const
Invoke the getter.
Definition: Property.h:138
Definition: GnashKey.h:166
void setReachable() const
Mark this property as being reachable (for the GC)
Definition: Property.h:398
bool visible(const Property &prop, int version)
Is this member supposed to be visible by a VM of given version ?
Definition: Property.h:431
bool setValue(as_object &this_ptr, const as_value &value) const
Set value of this property.
Definition: Property.cpp:133
Property(const ObjectURI &uri, as_c_function_ptr getter, as_c_function_ptr setter, const PropFlags &flags, bool destroy=false)
Definition: Property.h:310
as_value getCache() const
Get internal cached value of this property.
Definition: Property.cpp:127
tuple v
Definition: test.py:11
const FillStyle::Fill & _a
Definition: FillStyle.cpp:59
bool readOnly(const Property &prop)
is this a read-only member ?
Definition: Property.h:425
void set(const fn_call &fn)
Invoke the setter.
Definition: Property.h:144
const PropFlags & getFlags() const
accessor to the properties flags
Definition: Property.h:330
Property(const Property &p)
Copy constructor.
Definition: Property.h:321
Definition: GnashKey.h:132
bool test() const
Definition: PropFlags.h:94
void markReachableResources() const
Definition: Property.h:159
Definition: GnashKey.h:162
const ObjectURI & uri() const
The name-namespace pair (ObjectURI) of this Property.
Definition: Property.h:393
#define DSOTEXPORT
Definition: dsodefs.h:63
void clearVisible(int swfVersion)
Clear visibility flags.
Definition: Property.h:390
Definition: GnashKey.h:95
Parameters/environment for builtin or user-defined functions callable from ActionScript.
Definition: fn_call.h:107
Protect from assigning a value.
Definition: PropFlags.h:42
void setFlags(const PropFlags &flags) const
Set the flags of the property.
Definition: Property.h:333
void setReachable() const
Set any object value as reachable (for the GC)
Definition: as_value.cpp:692
ActionScript Function, either builtin or SWF-defined.
Definition: as_function.h:62
GetterSetter(as_function *getter, as_function *setter)
Construct a user-defined getter-setter.
Definition: Property.h:126
void clear_visible(int swfVersion)
Definition: PropFlags.h:108