📄 objects.txt
字号:
.. _objects-section:Ambulant design, main objects =============================Last updated for Ambulant version 1.8.Introduction------------This document describes the function of various of the more importantobjects and interfaces in the Ambulant Player. If you haven't already doneso it is probably a good idea to first read the `Overall design`_ and `walkthrough`_ documents. The first one explains the design principles andsome of the choices made, the second one is a brief walkthrough of how theplayer loads, parses and plays a SMIL document.The nitty-gritty details of these objects, on a level interesting todevelopers, are available too, in the `API documentation`_. This documentmay need to be regenerated, see the README file in the `documentationdirectory`_ if it doesn't seem to exist.AmbulantPlayer interfaces-------------------------- `Refcounting protocol`_. A lowlevel interface shared by many objects.- `Player Interface`_. This is the toplevel object.- `Parser Interface`_. Describes the interfaces to the XML parser.- `Datasource interface`_. The interface used to get external data into the program.- `Playable interface`_. This interface makes media items appear on the screen.- `Layout interface`_. This interface is used to determine where those media items show up.- `GUI window interface`_. This interface is used to create new windows.- `Animation interface`_. The interface used for SMIL animation.AmbulantPlayer Objects----------------------- `Gui_player`_. Convenience object wrapping a document and player.- `Clocks`_. These advance a virtual time.- `Event processor`_. This is the mainloop plus the event/callback mechanism.- `Document`_. The representation of a SMIL document.- `Node`_. The representation of the DOM tree.- `Transitions`_. Classes to do visual transitions.- `Timeline`_. This is a description of another scheduler: the MMS scheduler. This scheduler has a much simpler structure than the SMIL 2.1 scheduler. You may notice that the core of the player, the SMIL 2.1 scheduler, is notmentioned here. It is not documented, but (a) it is hardly ever necessary tomodify it, and (b) it follows the pseudocode in the W3C SMIL standardfairly closely.There are also additional low-level objects like ``thread`` and ``critical_section``that are not described here. See the `API documentation`_ for details.Refcounting protocol--------------------The `refcounting protocol` is contained in the file ``lib/refcount.h``. It needs tobe implemented only by objects that are truly shared, i.e. any object whoselifetime is not predetermined by some other object. New instances of refcountedobjects are created using the operator new. Any object that needs to sharea particular instance calls ``add_ref()`` against this instance. The creatorof the refcounted object and any sharer are responsible to call the ``release()``method of the object when they don't need the object any more. Player Interface----------------The player is the top-level object. When it is created you pass a DOM tree,a ``factories`` structure containing references to the ``playable_factory``,``datasource_factory`` and ``window_factory`` and an embedder object used forcallbacks to the GUI (on state changes, opening of external documents, etc).There is a `UML diagram for player`_ showing how the player relates to various other objects.Player implementations----------------------There are currently two implementations of the player interface: ``smil_player`` and``mms_player``. The first one is the all-singing-all-dancing SMIL 2.1 player,the second one can play MMS documents, which use a very restricted subset of SMIL 1.0.A concise walkthrough of how the ``smil_player`` operates is given in the `walkthrough`_document.Gui_player----------A convenience class that can be used as the framework for implementing themainloop class of an embedding application. It holds the document datastructures,the player and the factories needed.There is a `UML diagram for gui_player`_ showing this class and its relations.Parser interface----------------The XML parser roughly follows a SAX interface. To use it you provide it with objectshaving the ``sax_content_handler`` and ``sax_error_handler`` interfaces. You thenfeed your document to the parser and it will call back through those interfaces.There is a `UML diagram for parser`_ showing how these classes relates to each other.Parser implementations----------------------There are currently two parser implementations, ``expat_parser`` uses James Clark's`expat` parser, which is a fast and lean no-frills parser. ``xerces_parser`` usesthe Apache `Xerces` library, which is at the other extreme of the spectrum: it can dodocument validation with both DTDs and Schemas and lots of other wonderful things. Butthis comes at the price of a rather hefty memory footprint.Datasource interface--------------------There are actually a couple of these interfaces, but they are similar. Their functionis to implement URL retrieval schemes or file I/O and get external data to mediahandlers and other modules requiring data access.The general interface is that a datasource is acquired through a ``datasource_factory``interface, which passes the URL to the various implementations until one is found thatcan handle it and returns a ``datasource`` object. The client then calls the ``start``method on this object, passing a callback routine, and the datasource will arrange for thecallback to be called as soon as data is available. No new callbacks will be doneuntil a new call to ``start()`` is made, and the datasource has a buffer that can be limited,so this design allows for flow control over the net, if required.There are specialised datasource interfaces for audio and video, that can handle extra thingslike converting audio from mp3 format to linear samples, or demultiplexing an audio/videostream.There is a `UML diagram for datasource`_ showing how these classes relates to each otherand a `UML diagram for demux datasource`_ extending that for classes that demultiplex audioand video.There is also a `UML state diagram for datasource`_ showing the state machine that adatasource should adhere to.Playable interface------------------The ``playable`` interface is implemented by what are usually called a media handlersor media renderers: it is this interface the scheduler uses to make things appearon the screen (or sound out of the speakers, or otherwise do their thing).Playables are created through ``global_playable_factory``, which has references toall playable implementations and asks them in order whether they can handle playbackof this specific DOM node, until one matches.When the playable is started it is provided with a ``playable_notification`` object(implemented by the scheduler), which is where it can send its status messages (suchas ``stopped()`` when the media is finished, or ``clicked()`` when the user clicks the mouseover the media item).Most playables have an accompanying interface, ``renderer``, which controls where themedia item is rendered (non-rendering items such as SMIL animations are the exceptionto this rule). There is a `UML diagram for playable`_ showing how these classes relates to each other.There is also a `UML state diagram for playable`_ showing the state machine that aplayable should adhere to.Playable implementations------------------------While some media handlers implement the playable from scratch (an example is theaforementioned SMIL animation handler) there are a number of convenience classesthat implement functionality shared by many media handlers. These are:- ``playable_imp`` which handles some bookkeeping having to do with the ``playable_notification`` and ``event_processor``.- ``renderer_playable`` which augments that with a ``renderer`` interface and the bookkeeping required for that.- ``renderer_playable_ds`` which adds ``datasource`` creation and bookkeeping to that.- ``renderer_playable_dsall`` which builds on that again and collects all data before requiring further action. There is a `UML diagram for renderer_playable`_ showing how these classes relates to each other.Layout interface----------------The layout manager determines where media items appear, and also governs things likez-ordering, background colors for regions and such.The central interface is the ``surface``, which is the object passed to a ``renderer``.Whenever a renderer has something new to show it calls ``need_redraw()`` on thisinterface. Whenever it is time to actually redraw something the ``surface`` calls``redraw()`` on the ``renderer``.The ``layout_manager`` interface maps DOM nodes to the ``surface`` objects on which theyshould play back.There are two more auxiliary interfaces that are not strictly necessary but usedby the layout implementation for historical reasons: ``surface_template`` and ``surface_factory``. These interfaces are used to create subregions and toplevelwindows, respectively.There is a `UML diagram for layout`_ showing how these classes relates to each other.Layout implementation---------------------The SMIL 2.1 implementation of ``surface``, ``surface_template`` and ``surface_factory``are the classes ``passive_region`` and ``passive_root_layout``.There is a `UML diagram for region`_ showing how these classes relates to each other.GUI window interface--------------------This is the abstract interface used to create new windows and tie them to thelayout implementation. The implementation is machine-dependent, obviously, and usuallysupplied by the hosting application.In addition there is the ``gui_events`` interface which goes the other way:it is exposed by the layout implementation, and used by the machine dependentwindow implementation to communicate things like redraw requests.There is a `UML diagram for window`_ showing how these classes relates to each other.Animation interface-------------------The animation interfaces are ``animation_destination`` and ``animation_notification``.The SMIL 2.1 playable uses these interfaces to change parameters and send notificationof those changes, respectively.There is a `UML diagram for animation`_ showing how these classes relates to each other.Clocks------All clocks adhere to the ``timer`` interface. This interfaceallows you to get the current time and the speed of the clock.An extended interface ``timer_control`` is also available, whichallows control over the clock: setting the speed and epoch of the timer,pausing and restarting it, etc.There is a companion interface ``timer_events`` that allows objects to get notificationof changes in timer speed.A machine-dependent implementation of ``timer`` can be obtained throughthe ``realtime_timer_factory`` method.An implementation of ``timer_control`` is also available: ``timer_control_impl``.Eventually there may be other implementations of ``timer``,such as clocks that are allowed to slip synchronization and other suchsemantics as required by SMIL.There is a `UML diagram for clocks`_ showing how these classes relates to each other.Event processor---------------The ``event_processor`` is the low-level scheduler of the system. It is apriority runqueue with methods to add callbacks, with an optional delay untilthe callback becomes elegible. There is a `UML diagram for event processor`_ showing how these classes relates to each other.Document--------The ``document`` class contains the DOM tree and some auxiliary data:- the ``node_context`` which can be used to lookup nodes by XML ID and to resolve relative URLs, and- the ``nscontext`` which stores information on the use of XML namespaces.There is a `UML diagram for document`_ showing how the document class relates to various other objects.Node----The ``node`` class represents a node in the DOM tree. Actually, our tree isn't100% compatible with DOM, but close enough. The ``node`` objects store the tag,attributes and data pertaining to the XML node. There are basic methodsto access the parent, next sibling and first child, to insert or remove nodes into a treeand more.In the actual code there is a compile-time switch ``WITH_EXTERNAL_DOM`` that governswhether the ``node`` class is abstract or not. If defined, ``node`` isequivalent to ``node_interface``, the abstract API, and ``node_impl`` is one possibleimplementation of it. If not defined ``node`` is equivalent to ``node_impl``, whichleads to a more efficient implementation with inline methods and such. Thishelps on low-power machines.There are two auxiliary classes that augment the node functionality using onlythese interfaces:- ``node_navigator`` uses the basic ``up()/down()/next()`` methods of node to build more complex navigation.- ``node_iterator`` is an iterator that allows you to iterate over a subtree.There is a `UML diagram for node`_ showing how these classes relates to each other.Transitions-----------The implementation of SMIL transitions is fairly complex, because there are verymany transition types and they also need to be implemented efficiently onmultiple platforms. The current implementation is fully based on inheritance,a model with delegation would probably result in a cleaner design.The central object is the ``transition_engine``, which also supplies to interfaceused by clients. It has ``begin()``, ``end()``, ``step()`` and ``next_step_delay()``methods, which the client (usually a media renderer) uses to control the transition.``next_step_delay()`` needs an explanation: it returns the delay until the enginewould like to get the next call to ``step()`` from the renderer.On top of this central object there is a multiple inheritance graph where one legis machine dependent, and does the actual bitblit operation to combine two images.The other leg is machine independent, but dependent on the actual transition type,and computes the parameters for the bitblit. These two then come together in a stubclass that has all the functionality for a specific transition type on a specificplatform.There is a `UML diagram for transitions`_ showing how these classes relates to each other.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -