⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 overall.txt

📁 彩信浏览器
💻 TXT
字号:
.. _Overall-design-section:Ambulant design, overall========================Last updated for Ambulant version 1.8.Introduction------------This chapter gives a quick overview of various of the design criteriaunderlying the Ambulant Player. It actually started life as that design criteriadocument, hence it also has information on solutions we decided not to use, plusthe reasons why we made those choices.Design process--------------The design consists of a mixed bag of technologies:- Text files such as this one for informal descriptions. They are marked  up as reStructuredText_, a format easily converted to HTML  but also readable in source form.- C++ header files for class definitions and such.- Image files for UML pictures.  .. _reStructuredText: http://docutils.sourceforge.net/rst.html  If possible all design documents will carry a notice stating forwhich version of Ambulant they were last updated, so it is relativelyeasy to spot outdated (or potentially outdated) documents.    Global structure----------------To be able to use the codeto create, say, a plugin SMIL renderer for use in a browser we need a global"playback engine" object that has all the others hanging off it (plus factorymethods to create them, etc). To support this we have a global object ``player``that is the controller of all aspects of playback of a single SMIL document.In addition we use factories for creating things like renderers, file readers,parsers and windows. These factories are populated by the main program and thenused during document playback.With a structure like this the application itself becomes basically a skeletonembedder: it is responsible for the GUI, handling open/open URL/quit/etc, it createsplayback engine objects when needed and has a small number of callbacks for"create window" and such.In addition, because the main program is responsible for creating all the factoriesit should be possible to create a different main program that does not actuallyrender anything, but only prints on stdout what should happen at what time, orany other form of symbolic execution.Replaceable components----------------------AmbulantPlayer is intended to be a research system, and therefore all componentsshould be easy to replace without interfering with the rest of the system. Thisallows a researcher to concentrate on one issue, such as network protocols orscheduling algorithms, while the rest of the system is usable as-is.This replaceability is incorporated in the design through two means:- Clear well-defined APIs between the various parts of the system;- Factory functions to create most objects.In addition, the whole external API is also available in Python, to facilitaterapid prototyping.run-time system---------------Because we have a C++ implementationwe cannot rely on refcounting or garbage collection in the underlying runtime.lib/refcount.h has a simple refcounting implementation that is used forgarbage collection.Ref-counting should only be used when it is absolutely needed, it adds anoverhead and some complexity since it can not happen automatically. Onthe other hand there are some cases where it simplifies the code  a lot.If I judge from my code and the code of others I have seen, only veryfew objects need ref counting. First, objects owned by a class, andquite all are, never need to be ref counted. You just delete them.Ref-counting is needed when objects containing references are shared bycompletely independent components.The architecture is fairly tightly coupled. The original ideaof allowing the high-level scheduler to live on a different machine, precomputingschedules and ending these to a low level scheduler, isn't going to workfor SMIL without putting almost all SMIL complexity in the low-level scheduler.main loop---------The basic architecture is event-driven, with a smallnumber of worker threads picking up events from the event queue. The alternativeis to use multiple threads all over, but it seems event-driven is the betterchoice. An object that wants to use multiple threads can do so more easilyon an event infrastructure than the other way around, but these threads are"somebody else's problem", as they are hidden from the rest of the architecture.At first glance that it appears some objects, such as a renderer,would benefit from a threaded architecture it turns out this isn't really so.The naive threaded implementation::    while data = read_data():    	render_data(data)will not work, because many other things can also happen, such as a user-initiatedevent, or the timeline for the renderer being torn down. So, the naive loopsketched here will become hairy anyway, and look like::	while event = wait_for_some_interesting_event():		switch event:			case DATA: render_data(data)			case STOP: close_resources_and_exit()			...so we might as will split this out in the architecture.The event handler architecture needs an elaborate priority scheme, that is expressiveenough that the best execution order of things that happen "at the same time"is automatic.Factory pattern---------------There are various factories that follow a common pattern. There is a clientinterface, called something like ``playable_factory``, that can be used to create``playable`` objects. If the factory cannot create the object it returns ``NULL``.This factory interface is implemented by all the providers of objects that have the``playable`` interface. For example, the implementation of a video renderer for Cocoa on MacOSX will consist of a ``cocoa_video_playable`` implementation anda ``cocoa_video_playable_factory`` implementation.The core also has a provider interface, usually called``global_playable_factory``. This interface has a method ``add_playable_factory``that the playable provider uses to register its ``playable_factory``. Then,when a client uses the ``global_playable_factory`` to create a playableit will iterate over all playable factories until one is found that can createthe object.These ``global_playable_factory`` objects should be singletons, but in thecurrent implementation this isn't always true. Also, the ``global_`` namingconvention isn't strictly followed for all factories.Machine-dependent code----------------------The general way to handle machine-dependency is to create a machine-independentabstract base class, plus machine-dependent subclasses. Then there is a factoryfunction that creates a machine-dependent instance and returns it castedto its machine-independent base class.With this scheme we can handle machine-dependent extensions to the base classeasily: modules using these extensions declare objects of the subclass andcall the initializer directly in stead of through the factory function.The scheme does not work for all objects, however: it breaks if we want tocreate static copies of the objects. For classes for which this is the case,such as the ``critical_region`` object, we declare an abstract object ``base_critical_section`` in``lib/abstract_mtsync.h``, subclass that as ``PLATFORM::critical_section``in ``lib/PLATFORM/PLATFORM_mtsync.h``,conditionally include that in ``lib/mtsync.h`` and create an empty subclass``critical_section`` of it. In case you really need a preprocessor define to trigger machine-dependentcode on: ``ambulant/config.h`` defines a number of macros like``AMBULANT_PLATFORM_UNIX``, ``AMBULANT_PLATFORM_LINUX``, ``AMBULANT_PLATFORM_MACOS``, ``AMBULANT_PLATFORM_WIN32`` and ``AMBULANT_PLATFORM_WIN32_WCE``. Use of these ispreferred over platorm-native defines.integrating third-party tools-----------------------------We need to be able to use existing toolkits that take work out of our hands.Think of QuickTime and DirectX, where you basically pass a URL and say "play" andhave nothing to worry about anymore. Also, existing URL access libraries (suchas the caching infrastructure on windows) and a third party RTSP library needto be used. This also means we don't have to handle firewalls and what more.An informal `dataflow diagram`_ is available showing the various ways inwhich media bits can go from their source (far away on the net) to the screen.We would like to be able to re-use existing (Explorer, Netscape) pluginswhen applicable, but no work on this has been done yet.Other languages---------------The full Ambulant Player API is also available in Python, with full two-way bridgingbetween the languages (allowing not only method calls back and forth, but alsosubclassing C++ baseclasses in Python as well as Python baseclasses in C++).Bridging to other languages (Java, C#) is not currently on our agenda, butgiven the Python bridge it should not be too difficult. We are always open tohelping people interested in doing the work...

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -