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 <functional>
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(
152  std::bind(SetUnderlying(), std::placeholders::_1, v), _getset);
153  }
154 
156  as_value getCache() const {
157  return boost::apply_visitor(GetUnderlying(), _getset);
158  }
159 
160  void markReachableResources() const {
161  boost::apply_visitor(MarkReachable(), _getset);
162  }
163 
164 private:
165 
167  class UserDefinedGetterSetter
168  {
169  public:
170 
171  UserDefinedGetterSetter(as_function* get, as_function* set)
172  :
173  _getter(get),
174  _setter(set),
175  _underlyingValue(),
176  _beingAccessed(false)
177  {}
178 
180  as_value get(const fn_call& fn) const;
181 
183  void set(const fn_call& fn);
184 
186  const as_value& getUnderlying() const { return _underlyingValue; }
187 
189  void setUnderlying(const as_value& v) { _underlyingValue = v; }
190 
191  void markReachableResources() const;
192 
193  private:
194 
198  //
201  class ScopedLock : boost::noncopyable
202  {
203  public:
204 
205  explicit ScopedLock(const UserDefinedGetterSetter& na)
206  :
207  _a(na),
208  _obtainedLock(_a._beingAccessed ? false : true)
209  {
210  // If we didn't obtain the lock it would be true anyway,
211  // but it's probably polite to avoid touching it.
212  if (_obtainedLock) _a._beingAccessed = true;
213  }
214 
215  ~ScopedLock() { if ( _obtainedLock) _a._beingAccessed = false; }
216 
218  //
223  bool obtainedLock() const { return _obtainedLock; }
224 
225  private:
226 
227  const UserDefinedGetterSetter& _a;
228  bool _obtainedLock;
229 
230  };
231 
232  as_function* _getter;
233  as_function* _setter;
234  as_value _underlyingValue;
235  mutable bool _beingAccessed;
236  };
237 
239  class NativeGetterSetter
240  {
241  public:
242 
243  NativeGetterSetter(as_c_function_ptr get, as_c_function_ptr set)
244  :
245  _getter(get), _setter(set) {}
246 
248  as_value get(const fn_call& fn) const {
249  return _getter(fn);
250  }
251 
253  void set(const fn_call& fn) {
254  _setter(fn);
255  }
256 
258  void markReachableResources() const {}
259 
260  private:
261  as_c_function_ptr _getter;
262  as_c_function_ptr _setter;
263  };
264 
265  boost::variant<UserDefinedGetterSetter, NativeGetterSetter> _getset;
266 
267 };
268 
270 //
272 //
276 class Property
277 {
278 
280  struct SetReachable : boost::static_visitor<>
281  {
282  result_type operator()(const as_value& val) const {
283  val.setReachable();
284  }
285  result_type operator()(const GetterSetter& gs) const {
286  return gs.markReachableResources();
287  }
288  };
289 
290 public:
291 
293  PropFlags flags)
294  :
295  _bound(value),
296  _uri(std::move(uri)),
297  _flags(std::move(flags)),
298  _destructive(false)
299  {}
300 
302  as_function* getter, as_function* setter,
303  PropFlags flags, bool destroy = false)
304  :
305  _bound(GetterSetter(getter, setter)),
306  _uri(std::move(uri)),
307  _flags(std::move(flags)),
308  _destructive(destroy)
309  {}
310 
312  as_c_function_ptr setter, PropFlags flags,
313  bool destroy = false)
314  :
315  _bound(GetterSetter(getter, setter)),
316  _uri(std::move(uri)),
317  _flags(std::move(flags)),
318  _destructive(destroy)
319  {}
320 
322  const PropFlags& getFlags() const { return _flags; }
323 
325  void setFlags(const PropFlags& flags) const {
326  _flags = flags;
327  }
328 
330  //
338  DSOTEXPORT as_value getValue(const as_object& this_ptr) const;
339 
341  //
347  as_value getCache() const;
348 
350  //
356  void setCache(const as_value& v);
357 
359  //
374  bool setValue(as_object& this_ptr, const as_value &value) const;
375 
377  bool isGetterSetter() const {
378  return _bound.type() == typeid(GetterSetter);
379  }
380 
382  void clearVisible(int swfVersion) { _flags.clear_visible(swfVersion); }
383 
385  const ObjectURI& uri() const {
386  return _uri;
387  }
388 
390  void setReachable() const {
391  return boost::apply_visitor(SetReachable(), _bound);
392  }
393 
394 private:
395 
396  // Store the various types of things that can be held.
397  typedef boost::variant<as_value, GetterSetter> BoundType;
398 
400  mutable BoundType _bound;
401 
403  ObjectURI _uri;
404 
406  mutable PropFlags _flags;
407 
408  // If true, as soon as getValue has been invoked once, the
409  // returned value becomes a fixed return (though it can be
410  // overwritten if not readOnly)
411  mutable bool _destructive;
412 
413 };
414 
416 inline bool
417 readOnly(const Property& prop) {
418  return prop.getFlags().test<PropFlags::readOnly>();
419 }
420 
422 inline bool
423 visible(const Property& prop, int version) {
424  return prop.getFlags().get_visible(version);
425 }
426 
427 } // namespace gnash
428 
429 #endif // GNASH_PROPERTY_H
Definition: GnashKey.h:147
bool test() const
Definition: PropFlags.h:94
Holder for getter/setter functions.
Definition: Property.h:44
ActionScript value type.
Definition: as_value.h:94
Property(ObjectURI uri, const as_value &value, PropFlags flags)
Definition: Property.h:292
An abstract property.
Definition: Property.h:276
Definition: GnashKey.h:131
uri
Definition: test.py:12
v
Definition: test.py:11
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
void setReachable() const
Mark this property as being reachable (for the GC)
Definition: Property.h:390
as_value(* as_c_function_ptr)(const fn_call &fn)
Definition: Property.h:34
bool get_visible(int swfVersion) const
Get version-based visibility.
Definition: PropFlags.h:99
The base class for all ActionScript objects.
Definition: as_object.h:161
void setCache(const as_value &v)
Set the cache value (for user-defined getter-setters)
Definition: Property.h:150
as_value getCache() const
Get the cache value (for user-defined getter-setters)
Definition: Property.h:156
A URI for describing as_objects.
Definition: ObjectURI.h:44
bool isGetterSetter() const
Is this a getter/setter property?
Definition: Property.h:377
Definition: GnashKey.h:166
bool visible(const Property &prop, int version)
Is this member supposed to be visible by a VM of given version ?
Definition: Property.h:423
void markReachableResources() const
Definition: Property.h:160
Property(ObjectURI uri, as_c_function_ptr getter, as_c_function_ptr setter, PropFlags flags, bool destroy=false)
Definition: Property.h:311
bool readOnly(const Property &prop)
is this a read-only member ?
Definition: Property.h:417
Definition: GnashKey.h:132
#define DSOTEXPORT
Definition: dsodefs.h:63
const ObjectURI & uri() const
The name-namespace pair (ObjectURI) of this Property.
Definition: Property.h:385
const PropFlags & getFlags() const
accessor to the properties flags
Definition: Property.h:322
void setFlags(const PropFlags &flags) const
Set the flags of the property.
Definition: Property.h:325
Property(ObjectURI uri, as_function *getter, as_function *setter, PropFlags flags, bool destroy=false)
Definition: Property.h:301
void clearVisible(int swfVersion)
Clear visibility flags.
Definition: Property.h:382
Definition: GnashKey.h:165
Definition: GnashKey.h:95
Parameters/environment for builtin or user-defined functions callable from ActionScript.
Definition: fn_call.h:117
Protect from assigning a value.
Definition: PropFlags.h:42
void setReachable() const
Set any object value as reachable (for the GC)
Definition: as_value.cpp:691
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