root/libcore/parser/sprite_definition.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// sprite_definition.h:  Holds immutable data for a sprite, for Gnash.
//
//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
//   2011 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_SPRITE_DEFINITION_H
#define GNASH_SPRITE_DEFINITION_H

#include <boost/intrusive_ptr.hpp>
#include <boost/cstdint.hpp>
#include <string>
#include <map>
#include "smart_ptr.h" 
#include "movie_definition.h" // for inheritance
#include "log.h"
#include "SWFRect.h"
#include "StringPredicates.h" // StringNoCaseLessThan

// Forward declarations
namespace gnash {
        class SWFStream;
        class as_function;
    class RunResources;
}

namespace gnash
{


/// \brief
/// Holds the immutable data for a sprite, as read from
/// as SWF stream.
/// @@ should *not* derive from movie_definition, probably!
///
class sprite_definition : public movie_definition
{

public:

        /// \brief
        /// Read the sprite info from input stream.
        //
        /// A sprite definition consists of a series control tags.
        ///
        /// @param m
        ///     the Top-Level movie_definition this sprite is read
        ///     from (not a sprite_definition!)
        ///
        /// @param in
        ///     The stream associated with the sprite. It is assumed
        ///     to be already positioned right before the frame count
        ///
        sprite_definition(movie_definition& m, SWFStream& in,
            const RunResources& runResources, boost::uint16_t id);

        /// Destructor, releases playlist data
        ~sprite_definition();

        /// Register a class to this definition.
        //
        /// New instances of this symbol will get the given class
        /// interface.
        ///
        /// @param the_class
        ///     The class constructor to associate with
        ///     new instances of this DisplayObject. If NULL
        ///     new instances will get the MovieClip interface.
        ///
        void registerClass(as_function* the_class);

        /// Get the Class registered to this definition.
        as_function* getRegisteredClass() const {
                return registeredClass;
        }

    virtual void incrementLoadedFrames() {
        ++m_loading_frame;
    }

        // overload from movie_definition
        virtual size_t get_width_pixels() const { return 1; }

        // overload from movie_definition
        virtual size_t get_height_pixels() const { return 1; }

        // overload from movie_definition
        virtual size_t get_frame_count() const { return m_frame_count; }

        /// \brief
        /// Return total bytes of the movie from which this sprite
        /// has been read.
        ///
        virtual size_t get_bytes_total() const
        {
                return m_movie_def.get_bytes_total();
        }

        /// \brief
        /// Return the number of bytes loaded from the stream of the
        /// the movie from which this sprite is being read.
        ///
        virtual size_t get_bytes_loaded() const
        {
                return m_movie_def.get_bytes_loaded();
        }

        virtual float   get_frame_rate() const
        {
                return m_movie_def.get_frame_rate();
        }

        const SWFRect& get_frame_size() const
        {
                abort();
                static const SWFRect unused;
                return unused;
        }

        // Return number of frames loaded (of current sprite)
        virtual size_t  get_loading_frame() const { return m_loading_frame; }

        virtual int     get_version() const
        {
                return m_movie_def.get_version();
        }

        /// Overridden just for complaining  about malformed SWF
        virtual void add_font(int /*id*/, boost::intrusive_ptr<Font> /*ch*/)
        {
                IF_VERBOSE_MALFORMED_SWF (
                log_swferror(_("add_font tag appears in sprite tags"));
                );
        }

        /// Delegate call to associated root movie
        virtual Font* get_font(int id) const
        {
                return m_movie_def.get_font(id);
        }

        /// Delegate call to associated root movie
        virtual CachedBitmap* getBitmap(int id) const
        {
                return m_movie_def.getBitmap(id);
        }

        /// Overridden just for complaining  about malformed SWF
        virtual void addBitmap(int /*id*/, boost::intrusive_ptr<CachedBitmap> /*im*/)
        {
                IF_VERBOSE_MALFORMED_SWF (
                log_swferror(_("add_bitmap_SWF::DefinitionTag appears in sprite tags"));
                );
        }

        /// Delegate call to associated root movie
        virtual sound_sample* get_sound_sample(int id) const
        {
                return m_movie_def.get_sound_sample(id);
        }

        /// Overridden just for complaining  about malformed SWF
        virtual void add_sound_sample(int id, sound_sample* sam)
        {
                // DEFINESOUND tags *are* allowed in a sprite context,
                // and it is *expected* for them to be registered into
                // the main dictionary.
                m_movie_def.add_sound_sample(id,sam);
        }

        // See dox in movie_definition.h
        virtual void set_loading_sound_stream_id(int id)
        {
                _loadingSoundStream = id;
        }

        // See dox in movie_definition.h
        virtual int get_loading_sound_stream_id() const
        {
                return _loadingSoundStream;
        }

    virtual boost::uint16_t exportID(const std::string& symbol) const {
        return m_movie_def.exportID(symbol);
    }
    
    virtual void registerExport(const std::string& s, boost::uint16_t id) {
        m_movie_def.registerExport(s, id);
    }

        /// \brief
        /// Get a SWF::DefinitionTag from this Sprite's root movie
        /// CharacterDictionary.
        ///
        virtual SWF::DefinitionTag*     getDefinitionTag(boost::uint16_t id) const
        {
            return m_movie_def.getDefinitionTag(id);
        }

        /// Delegate call to associated root movie
        virtual void addDisplayObject(boost::uint16_t id, SWF::DefinitionTag* c)
        {
                m_movie_def.addDisplayObject(id, c);
        }

        // Create a (mutable) instance of our definition.  The
        // instance is created to live (temporarily) on some level on
        // the parent movie's display list.
        //
        // overloads from SWF::DefinitionTag
        virtual DisplayObject* createDisplayObject(Global_as& gl,
            DisplayObject* parent) const;

        // See dox in movie_definition.h
        virtual void addControlTag(boost::intrusive_ptr<SWF::ControlTag> c)
        {
                m_playlist[m_loading_frame].push_back(c);
        }

private:

        void read(SWFStream& in, const RunResources& runResources);

        /// Top-level movie definition
        /// (the definition read from SWF stream)
        movie_definition& m_movie_def;

        typedef std::map<size_t, PlayList> PlayListMap;

        /// movie control events for each frame.
        PlayListMap m_playlist;

        // stores 0-based frame #'s
        typedef std::map<std::string, size_t, StringNoCaseLessThan> NamedFrameMap;
        NamedFrameMap _namedFrames;

        size_t m_frame_count;

        // Number of frames completely parsed 
        size_t m_loading_frame;

        // See dox in movie_definition.h
        virtual void add_frame_name(const std::string& name);

        // See dox in movie_definition
        bool get_labeled_frame(const std::string& label, size_t& frame_number)
        const;

        /// frame_number is 0-based
        const PlayList* getPlaylist(size_t frame_number) const
        {
                // Don't access playlist of a frame which has not been
                // completely parsed yet.
                //assert(frame_number < m_loading_frame);

                PlayListMap::const_iterator it = m_playlist.find(frame_number);
                if ( it == m_playlist.end() ) return NULL;
                else return &(it->second);
        }

        virtual const std::string& get_url() const
        {
                return m_movie_def.get_url();
        }

        /// \brief
        /// Ensure framenum frames of this sprite
        /// have been loaded.
        ///
        virtual bool ensure_frame_loaded(size_t framenum) const
        {
                // TODO: return false on timeout
                while ( m_loading_frame < framenum )
                {
                        log_debug(_("sprite_definition: "
                                "loading of frame %d requested "
                                "(we are at %d/%d)"),
                                framenum, m_loading_frame, m_frame_count);
                        // Could this ever happen ? YES ! See tuner_7_6_0_0_pandora.swf
                        return false;
                }
                return true;
        }

        /// The constructor to use for setting up the interface
        /// for new instances of this sprite
        //
    /// TODO: this really shouldn't be stored in an immutable definition.
        as_function* registeredClass;

        int     _loadingSoundStream;

protected:

        /// Mark reachable resources of a sprite_definition
        //
        /// Reachable resources are:
        ///     - registered class (registeredClass)
        ///
        void markReachableResources() const;
};


} // end of namespace gnash

#endif 

/* [<][>][^][v][top][bottom][index][help] */