From OpenHome

(Difference between revisions)
Jump to: navigation, search
(Topology1)
(Source Naming)
 
(145 intermediate revisions not shown)
Line 29: Line 29:
===Overview===
===Overview===
-
Topology1 maintains a collection of all discovered devices, that feature the '''Product Service'''. It presents the collection as a list of '''Product Service''' proxies.
+
Topology1 collects a list of '''Product Service''' devices from Network and exposes a collection of '''Products'''.
===Topology1===
===Topology1===
-
Topology1 requests a list of devices with the '''Product Service''', from Network, and watches this list for changes. It creates a corresponding list of '''ProxyProduct''' objects that is updated whenever the Network device list changes. The '''ProxyProduct''' list is exposed as '''Products''' which is of type IWatchableUnordered.
+
Topology1 watches a (Product Service) device list from '''Network''' and creates a corresponding list of '''ProxyProduct''' objects that is updated whenever the device list changes. The '''Products''' method exposes the '''ProxyProduct''' list as an IWatchableUnordered.
==Topology2 ==
==Topology2 ==
===Overview===
===Overview===
-
Topology2 collects the list of discovered '''products''' from '''Topology1''' and presents a collection of '''Groups'''. Each '''Group''' presents a '''Sources''' collection and pertinent properties and actions of the '''Product Service'''. Each '''Source''' presents the standard set of Source properties.
+
Topology2 collects the list of '''Products''' from '''Topology1''' and exposes a collection of '''Groups'''. Each '''Group''' exposes a '''Sources''' collection and pertinent properties and actions of the '''Product Service'''. Each '''Source''' exposes the standard set of Source properties.
===Topology2===
===Topology2===
-
Topology2 watches Topology1::Products and updates Topology2Group list whenever a ProxyProduct is added/removed from Topology1::Products
+
Topology2 watches '''Topology1::Products''' and creates a corresponding list of '''Topology2Group''' objects that is updated whenever '''Topology1::Products''' changes. The '''Groups''' method exposes the '''Topology2Group''' list as an IWatchableUnordered.
===Topology2Source===
===Topology2Source===
 +
Topology2Source exposes the three standard source properties: '''Name''', '''Visible''' and '''Type'''. The '''Index''' method exposes the source's position in the source list of '''Topology2Group'''.
 +
===Topology2Group===
===Topology2Group===
 +
Topology2Group watches the '''SourceXml''' property of its underlying '''ProxyProduct''' object. Source information retrieved from '''SourceXml''' is used to to create and update a list of '''Topology2Source''' objects. The '''Sources''' method exposes the '''Topology2Source''' list as an IWatchableUnordered.
==Topology3 ==
==Topology3 ==
===Overview===
===Overview===
-
Topology3 collects the list of '''Groups''' from '''Topology2''' and presents a collection of '''Groups''' each presenting a '''Sources''' collection, pertinent actions and properties of the '''Product Service''', a '''Sender''' property and a '''SetSender''' action.
+
Topology3 collects the list of '''Groups''' from '''Topology2''' and exposes a collection of '''Groups'''. Each '''Group''' exposes a '''Sources''' collection, pertinent actions and properties of the '''Product Service''', and a '''Sender''' property.
===Topology3===
===Topology3===
-
Topology3 watches Topology2::Groups and updates Topology3Group list whenever a Topology2Group is added or removed.
+
Topology3 watches '''Topology2::Groups''' to create and maintain a corresponding list of '''Topology3Group''' objects. A dedicated '''SenderWatcher''' is created for each '''Topology3Group''' that has a Sender attribute,  to monitor the '''Metadata''' property of its '''Sender Service''' . A dedicated '''ReceiverWatcher''' is created for each '''Topology3Group'''  to monitor both the '''Metadata''' and '''TransportState''' properties of its '''Receiver Service'''.
 +
 
 +
Topology3 marries receivers and senders by matching their '''Uri''' properties, reassigning the '''Sender''' property of each '''Topology3Group''' when changes are reported by the watchers. The '''Groups''' method exposes the '''Topology3Group''' list as an IWatchableUnordered.
===Topology3Group ===
===Topology3Group ===
-
===Receiver Watcher===
+
Topology3Group exposes all of the properties and actions of its underlying '''Topology2Group''' plus a '''Sender''' property. The Sender property holds a reference to a '''Sender''' object that reflects the Songcast sender device that the group's receiver source is listening to. The '''SenderEmpty''' object is used when no sender is selected or the selected sender is inactive.
-
===Sender Watcher===
+
 
 +
===ReceiverWatcher===
 +
ReceiverWatcher watches the '''Sources''' property of Topology3Group to find a source of type '''Receiver''' as an indicator of the existence of a '''Receiver service'''. If it exists, the '''Receiver service''' is subscribed to and its '''TransportState''' and '''Metadata''' properties are watched. When either of these two properties change Topology3 is notified via its '''ReceiverChanged''' method.
 +
 
 +
===SenderWatcher===
 +
SenderWatcher subscribes to it's group's '''Sender service''' to watch its '''Metadata''' property. When this property changes Topology3 is notified via its '''SenderChanged''' method.
==Topology4 ==
==Topology4 ==
===Overview===
===Overview===
-
Topology4 collects the list of '''Groups''' from '''Topology3''' and exposes a collection of '''Rooms''' each exposing a  collection of '''Groups''' with matching '''RoomName''' property.
+
Topology4 collects the list of '''Groups''' from '''Topology3''' and exposes a new collection of '''Rooms'''. Each '''Room''' in the new collection exposes a  collection of '''Groups''' with matching '''RoomName''' properties.
===Topology4===
===Topology4===
-
Topology4 watches Topology3::Groups and updates Topology4Room list whenever there is a change to the Room property of any Topology3Group. The Room property of each Topology3Group is monitored by a dedicated Topology4GroupWatcher.
+
Topology4 watches '''Topology3::Groups''' and creates a '''Topology4Room''' list that is updated whenever there is a change to the '''RoomName''' property of any '''Topology3Group'''. A dedicated '''Topology4GroupWatcher''' is created for each '''Topology3Group''' to watch its '''RoomName''' property. The Rooms method exposes the '''Topology4Room''' list as an IWatchableUnordered.
===Topology4Room ===
===Topology4Room ===
 +
Topology4Room maintains a collection of '''Topology4Group''' objects with matching '''RoomName''' properties. The collection contains at least one group. Groups are added and removed by the Topology4 class. The '''Name''' method exposes the '''Name''' property which reflects the common '''RoomName''' value shared by all groups in the collection. The '''SetStandby''' method sets the standby state of all groups. The '''Groups''' method exposes the collection of groups as an IWatchableUnordered.
 +
===Topology4GroupWatcher ===
===Topology4GroupWatcher ===
-
Updates Topology4 upon Room property change of Topology3Group.
+
Topology4GroupWatcher  watches the '''RoomName''' property of a single '''Topology3Group''' and updates '''Topology4''',  removing the group from one room and adding it to another, whenever its '''RoomName''' property changes.
==Topology5 ==
==Topology5 ==
===Overview===
===Overview===
-
Topology5 collects the list of '''Rooms''' from Topoolgy4 and organises the '''Groups''' in each room, evaluating their interrelationship as a hierarchical tree. It presents a list of '''Rooms''' each presenting lists of '''Roots''' and '''Sources'''. A Root is defined as a product whose outputs are '''not''' connected to the inputs of any other product. In essence a Root is the main product in the Room whose outputs are connected to the speakers and typically, once configured correctly, each '''Room''' will only contain one '''Root'''.
+
Topology5 collects the list of '''Rooms''' from '''Topology4''' and organises the products ('''Groups''') in each room, evaluating their interrelationship as a family tree of connected '''parents''' and '''children'''. It exposes a list of  '''Rooms''', with each '''Room''' exposing a list of parent products ('''Roots''') and a list of sources.  
-
===Topology5===
+
====Roots====
-
Topology5 watches Topology4::Rooms, updating Topology5Room list whenever a Topology4Room is added/removed.
+
Products in a room can be daisychained by connecting the outputs of one product to the inputs of another, creating a tree of devices. In such a setup, the '''Root''' (parent) of the tree (the product at the end of the chain) is the output for all the products in the room. Typically there should only be one '''Root''' in each room, whose outputs are connected to the speakers. A '''Root''' is thus defined as a product whose outputs are '''not''' connected to the inputs of any other product.
-
Each Room's '''Group''' list is filtered to remove all '''Child''' groups, and a super list of all sources of all groups in each room is maintained that is  filtered to remove any '''Parent''' sources. A '''Child''' group is defined as one whose outputs are connected to the inputs of another group. A '''Parent''' source is defined as one whose input is fed from the outputs of another (Child) group.
+
====Source Naming====
 +
It is not possible for a product to detect if other products are connected to its inputs. Topology, therefore, can only imply this through source naming configured by the user, as follows. If a '''source name''' on a product "ProductA" matches the '''device name''' of another product "ProductB", in the same room, it implies that the outputs of ProductB are connected to the inputs of that source on ProductA. In the family tree of products in a room, ProductA is the '''parent''' of ProductB and ProductB is a '''child''' of ProductA.
-
===Topology5Room ===
+
===Topology5===
 +
Topology5 watches '''Topology4::Rooms''' to create and maintain a corresponding collection of '''Topology5Room''' objects. The '''Rooms''' method exposes the collection of rooms as an IWatchableUnordered.
-
Topology5Room watches Topology4Room::Groups updating Topology3Group list whenever a Topology3Group is added/removed. The Standby, Name and Sources properties of each Topology3Group are then watched for changes. A dedicated Topology5GroupWatcher is employed to monitor Name and Sources of each group. Although the Standby state of each group is boolean, Topology5Room exposes a tristate Standby property. This is to accommodate a third state "mixed" when there is an inconsistent Standby state across all groups in the room. The Topology3Group list is used to maintain a corresponding Topology5Group list, a subset of which is exposed as a Roots list. A Root (ITopology5Root) is defined as a Topology5Group that does not have a Parent group. A super list of all Sources of every Root in the Room is exposed as Sources.
+
===Topology5Room ===
 +
Topology5Room maintains a Topology3Group list of by watching the Groups list of its underlying Topology4Room. A dedicated Topology5GroupWatcher is created for each group to watch its '''Name''' and '''Sources''' properties. Since all groups in the room may not share the same standby state, an additional "'''mixed'''" state is introduced to create a '''tristate Standby''' property. The '''Topology3Group''' list is used to maintain a corresponding '''Topology5Group''' list which is then filtered to obtain a '''Roots''' list. A super list of sources (Topology5Source) is then created by gathering all the sources of each Root replacing each source with its child group's sources where appropriate. The '''Roots''' method exposes the Roots list as an IWatchableUnordered. The '''Sources''' method exposes the Roots list as an IWatchableUnordered. The '''Standby''' method exposes the standby state of the room. The '''SetStandby''' method sets the standby state of all groups in the room. The '''Name''' method exposes the common room name shared by all groups in the room.
===Topology5Group ===
===Topology5Group ===
-
===Topology5Source ===
+
Topology5Group keeps track of it's '''parent''' and '''children''' groups, its currently active source, a list of its currently visible sources (expanded to include the sources of any child groups), a list of groups (from my group upwards) with the Volume service, a list of all child groups that have the Sender service.
 +
 
===Topology5GroupWatcher ===
===Topology5GroupWatcher ===
-
Monitors the two properties, Name and Sources, of Topology3Group, updating (CreateTree) Topology5Room when any poperty change occurs.
+
Monitors the '''Name''' and '''Sources''' properties of a specific '''Topology3Group''', updating '''Topology5Room''' whenever a change occurs.
 +
 
 +
===Topology5Source ===
 +
Topology5Source provides a number of methods that expose the standard source parameters, flags to the presence of the Info and Time services, the source's parent group, the group's device and a list of parent groups with the Volume service. Also provided is a method to reset the list of volume service groups, a method select the source and a factory method, '''CreatePreset''', that returns a '''MediaPresetExternal''' object.
 +
===MediaPresetExternal===
 +
MediaPresetExternal is an object that provides access to a single '''Topology5Source''' object via the standard '''IMediaPreset''' interface. It monitors the transport state of the Source by watching the '''Source''' property of the its parent '''Topology5Group'''. The state is exposed via the three IWatchable properties '''Playing''', '''Buffering''' and '''Selected'''. The '''Play''' method selects the source in its parent group.
==Services==
==Services==

Latest revision as of 16:38, 12 March 2015

Contents

ohTopology

Overview

ohTopology is a software stack which provides a means of controlling devices, on a local network, via their UPnP service actions. Devices are grouped based on their Room names and presented as a tree structure based on their interconnectivity. It consists of a number of distinct layers. Each layer focuses on exposing specific properties and actions that are intended to be utilised by the layers above. Clients of ohTopology need only interface directly with the highest layer of the stack to gain access to the properties and actions exposed by the lower layers.

Watchable System

Overview

Actions exposed by a layer can be called directly, but property values can only be monitored through a callback notification system (observer pattern). Properties are exposed as "watchable" values that may be monitored by "watcher" clients. When a (watchable) property changes, all of its watchers are automatically notified of the change and the property's new value. Watchers can be added and removed at any time. The IWatchable interface is used to expose single value properties and the IWatchableUnordered and IWatchableOrdered interfaces are used for multivalue property lists. Property client objects must conform to the appropriate Iwatchable/IWatchableUnordered/IWatchableOrdered interface for the property that they wish to observe.

Watchable Thread

Although ohTopology is designed to run on multithreaded platforms, actions are executed in a single thread through the use of a thread scheduler class, WatchableThread. Enforcing single threaded execution removes the burden of having to manage thread safety, simplifies debugging and reduces the risk of deadlock. The WatchableThread class provides three methods; Execute, Schedule and Assert.

Schedule Method

Schedule provides a mechanism for asynchronous callback. The specified callback is placed in a queue (FIFO) to be run on the watchable thread, in turn, at some point in the future. Schedule takes a functor, for the callback method, and a generic void* argument to be passed to the callback.

Execute Method

Execute provides a mechanism for synchronous callback. If called from the watchable thread it executes the callback immediately. Otherwise it schedules the callback, for execution on the watchable thread. In either case, it blocks until the callback has completed. Execute takes a functor for the callback method and a generic void* argument to be passed to the callback.

Assert Method

Assert provides a way of checking if the current thread is the watchable thread.

Injector

Network

Topology1

Overview

Topology1 collects a list of Product Service devices from Network and exposes a collection of Products.

Topology1

Topology1 watches a (Product Service) device list from Network and creates a corresponding list of ProxyProduct objects that is updated whenever the device list changes. The Products method exposes the ProxyProduct list as an IWatchableUnordered.

Topology2

Overview

Topology2 collects the list of Products from Topology1 and exposes a collection of Groups. Each Group exposes a Sources collection and pertinent properties and actions of the Product Service. Each Source exposes the standard set of Source properties.

Topology2

Topology2 watches Topology1::Products and creates a corresponding list of Topology2Group objects that is updated whenever Topology1::Products changes. The Groups method exposes the Topology2Group list as an IWatchableUnordered.

Topology2Source

Topology2Source exposes the three standard source properties: Name, Visible and Type. The Index method exposes the source's position in the source list of Topology2Group.

Topology2Group

Topology2Group watches the SourceXml property of its underlying ProxyProduct object. Source information retrieved from SourceXml is used to to create and update a list of Topology2Source objects. The Sources method exposes the Topology2Source list as an IWatchableUnordered.

Topology3

Overview

Topology3 collects the list of Groups from Topology2 and exposes a collection of Groups. Each Group exposes a Sources collection, pertinent actions and properties of the Product Service, and a Sender property.

Topology3

Topology3 watches Topology2::Groups to create and maintain a corresponding list of Topology3Group objects. A dedicated SenderWatcher is created for each Topology3Group that has a Sender attribute, to monitor the Metadata property of its Sender Service . A dedicated ReceiverWatcher is created for each Topology3Group to monitor both the Metadata and TransportState properties of its Receiver Service.

Topology3 marries receivers and senders by matching their Uri properties, reassigning the Sender property of each Topology3Group when changes are reported by the watchers. The Groups method exposes the Topology3Group list as an IWatchableUnordered.

Topology3Group

Topology3Group exposes all of the properties and actions of its underlying Topology2Group plus a Sender property. The Sender property holds a reference to a Sender object that reflects the Songcast sender device that the group's receiver source is listening to. The SenderEmpty object is used when no sender is selected or the selected sender is inactive.

ReceiverWatcher

ReceiverWatcher watches the Sources property of Topology3Group to find a source of type Receiver as an indicator of the existence of a Receiver service. If it exists, the Receiver service is subscribed to and its TransportState and Metadata properties are watched. When either of these two properties change Topology3 is notified via its ReceiverChanged method.

SenderWatcher

SenderWatcher subscribes to it's group's Sender service to watch its Metadata property. When this property changes Topology3 is notified via its SenderChanged method.

Topology4

Overview

Topology4 collects the list of Groups from Topology3 and exposes a new collection of Rooms. Each Room in the new collection exposes a collection of Groups with matching RoomName properties.

Topology4

Topology4 watches Topology3::Groups and creates a Topology4Room list that is updated whenever there is a change to the RoomName property of any Topology3Group. A dedicated Topology4GroupWatcher is created for each Topology3Group to watch its RoomName property. The Rooms method exposes the Topology4Room list as an IWatchableUnordered.

Topology4Room

Topology4Room maintains a collection of Topology4Group objects with matching RoomName properties. The collection contains at least one group. Groups are added and removed by the Topology4 class. The Name method exposes the Name property which reflects the common RoomName value shared by all groups in the collection. The SetStandby method sets the standby state of all groups. The Groups method exposes the collection of groups as an IWatchableUnordered.

Topology4GroupWatcher

Topology4GroupWatcher watches the RoomName property of a single Topology3Group and updates Topology4, removing the group from one room and adding it to another, whenever its RoomName property changes.

Topology5

Overview

Topology5 collects the list of Rooms from Topology4 and organises the products (Groups) in each room, evaluating their interrelationship as a family tree of connected parents and children. It exposes a list of Rooms, with each Room exposing a list of parent products (Roots) and a list of sources.

Roots

Products in a room can be daisychained by connecting the outputs of one product to the inputs of another, creating a tree of devices. In such a setup, the Root (parent) of the tree (the product at the end of the chain) is the output for all the products in the room. Typically there should only be one Root in each room, whose outputs are connected to the speakers. A Root is thus defined as a product whose outputs are not connected to the inputs of any other product.

Source Naming

It is not possible for a product to detect if other products are connected to its inputs. Topology, therefore, can only imply this through source naming configured by the user, as follows. If a source name on a product "ProductA" matches the device name of another product "ProductB", in the same room, it implies that the outputs of ProductB are connected to the inputs of that source on ProductA. In the family tree of products in a room, ProductA is the parent of ProductB and ProductB is a child of ProductA.

Topology5

Topology5 watches Topology4::Rooms to create and maintain a corresponding collection of Topology5Room objects. The Rooms method exposes the collection of rooms as an IWatchableUnordered.

Topology5Room

Topology5Room maintains a Topology3Group list of by watching the Groups list of its underlying Topology4Room. A dedicated Topology5GroupWatcher is created for each group to watch its Name and Sources properties. Since all groups in the room may not share the same standby state, an additional "mixed" state is introduced to create a tristate Standby property. The Topology3Group list is used to maintain a corresponding Topology5Group list which is then filtered to obtain a Roots list. A super list of sources (Topology5Source) is then created by gathering all the sources of each Root replacing each source with its child group's sources where appropriate. The Roots method exposes the Roots list as an IWatchableUnordered. The Sources method exposes the Roots list as an IWatchableUnordered. The Standby method exposes the standby state of the room. The SetStandby method sets the standby state of all groups in the room. The Name method exposes the common room name shared by all groups in the room.

Topology5Group

Topology5Group keeps track of it's parent and children groups, its currently active source, a list of its currently visible sources (expanded to include the sources of any child groups), a list of groups (from my group upwards) with the Volume service, a list of all child groups that have the Sender service.

Topology5GroupWatcher

Monitors the Name and Sources properties of a specific Topology3Group, updating Topology5Room whenever a change occurs.

Topology5Source

Topology5Source provides a number of methods that expose the standard source parameters, flags to the presence of the Info and Time services, the source's parent group, the group's device and a list of parent groups with the Volume service. Also provided is a method to reset the list of volume service groups, a method select the source and a factory method, CreatePreset, that returns a MediaPresetExternal object.

MediaPresetExternal

MediaPresetExternal is an object that provides access to a single Topology5Source object via the standard IMediaPreset interface. It monitors the transport state of the Source by watching the Source property of the its parent Topology5Group. The state is exposed via the three IWatchable properties Playing, Buffering and Selected. The Play method selects the source in its parent group.

Services

Overview

Service

ServicePlaylist

ServiceRadio

ServiceSender

ServiceReceiver

ServiceVolume

ServiceInfo

ServiceProduct