// CharacterProxy.h - rebindable DisplayObject reference, for Gnash // // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software // Foundation, Inc // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #ifndef GNASH_CHARACTER_PROXY_H #define GNASH_CHARACTER_PROXY_H #include // Forward declarations namespace gnash { class DisplayObject; } namespace gnash { /// A proxy for DisplayObject pointers. // /// The proxy will store a pointer to a DisplayObject until the /// DisplayObject is destroyed, in which case it will only store the original /// target path of it and always use that for rebinding when needed. /// class CharacterProxy { mutable DisplayObject* _ptr; mutable std::string _tgt; static DisplayObject* findDisplayObjectByTarget(const std::string& target); /// If we still have a sprite pointer check if it was destroyed /// in which case we drop the pointer and only keep the target. void checkDangling() const; public: /// Construct a CharacterProxy pointing to the given sprite CharacterProxy(DisplayObject* sp) : _ptr(sp) { checkDangling(); } /// Construct a copy of the given CharacterProxy // /// @param sp /// The CharacterProxy to make a copy of. /// NOTE: if the given proxy is dangling, this proxy /// will also be dangling. If you want to /// create a non-dangling proxy you can /// use the constructor taking a DisplayObject /// as in CharacterProxy newProxy(oldProxy.get()) /// CharacterProxy(const CharacterProxy& sp) { sp.checkDangling(); _ptr=sp._ptr; if ( ! _ptr ) _tgt=sp._tgt; } /// Make this proxy a copy of the given one // /// @param sp /// The CharacterProxy to make a copy of. /// NOTE: if the given proxy is dangling, this proxy /// will also be dangling. If you want to /// create a non-dangling proxy you can /// use the constructor taking a DisplayObject /// as in CharacterProxy newProxy(oldProxy.get()) /// CharacterProxy& operator=(const CharacterProxy& sp) { sp.checkDangling(); _ptr=sp._ptr; if ( ! _ptr ) _tgt=sp._tgt; return *this; } /// Get the pointed sprite, either original or rebound // /// @return the currently bound sprite, NULL if none /// DisplayObject* get(bool skipRebinding=false) const { if ( skipRebinding ) return _ptr; // set _ptr to NULL and _tgt to original target if destroyed checkDangling(); if ( _ptr ) return _ptr; else return findDisplayObjectByTarget(_tgt); } /// Get the sprite target, either current (if not dangling) or /// bound one. std::string getTarget() const; /// Return true if this sprite is dangling // /// Dangling means that it doesn't have a pointer to the original /// sprite anymore, not that it doesn't point to anything. /// To know if it points to something or not use get(), which will /// return NULL if it doesn't point to anyhing. /// bool isDangling() const { checkDangling(); return !_ptr; } /// \brief /// Two sprite_proxies are equal if they point to the /// same sprite /// bool operator==(const CharacterProxy& sp) const { return get() == sp.get(); } /// Set the original sprite (if any) as reachable // /// NOTE: if this value is dangling, we won't keep anything /// alive. /// void setReachable() const; }; } // end namespace gnash #endif // GNASH_CHARACTER_PROXY_H