Updated Arch activate (markdown)

Neil Dorin
2022-02-01 15:08:31 -07:00
parent a9cbd37df4
commit 8acf462af3

@@ -103,9 +103,51 @@ Each of the three activation phases operates in a try/catch block for each devic
## Interdependence
In any real-world system, devices and business logic need to talk to each other, otherwise, what's the point of all this coding? When creating your classes and configuration, it is best practice to _try_ not to "plug" one device into another during construction or activation. For example your touchpanel controller class has a `Display1` property that holds the display-1 object. Rather, it may be better to refer to the device as it is stored in the `DeviceManager` when it's needed using the static `DeviceManager.GetDeviceForKey(key)` method to get a reference to the device, which can be cast using various interfaces/class types, and then interacted with. This prevents objects from being referenced in places where the developer may later forget to dereference them, causing memory leak. This will become more important as Essentials becomes more able to be reconfigured at runtime.
In any real-world system, devices and business logic need to talk to each other, otherwise, what's the point of all this coding? When creating your classes and configuration, it is best practice to _try_ not to "plug" one device into another during construction or activation. For example your touchpanel controller class has a `Display1` property that holds the display-1 object. Rather, it may be better to refer to the device as it is stored in the `DeviceManager` when it's needed using the static `DeviceManager.GetDeviceForKey(key)` method to get a reference to the device, which can be cast using various interfaces/class types, and then interacted with. This prevents objects from being referenced in places where the developer may later forget to dereference them, causing memory leak. This will become more important as Essentials becomes more able to be reconfigured at runtime.
As an example, [connecting-based routing](https://github.com/PepperDash/Essentials/wiki/Connection-based-routing#essentials-connection-based-routing) uses these methods. When a route is requested, the collection of tielines and devices is searched for the devices and paths necessary to complete a route, but there are no devices or tie lines that are object-referenced in running code. It can all be torn down and reconfigured without any memory-management dereferencing, setting things to null.
As an example, [connection-based routing](https://github.com/PepperDash/Essentials/wiki/Connection-based-routing#essentials-connection-based-routing) uses these methods. When a route is requested, the collection of tielines and devices is searched for the devices and paths necessary to complete a route, but there are no devices or tie lines that are object-referenced in running code. It can all be torn down and reconfigured without any memory-management dereferencing, setting things to null.
## Device Initialization
Once the `DeviceManager` has completed the activation phase cycle for all devices, the devices themselves can be initialized. The `EssentialsDevice` class subscribes to the `DeviceManager.AllDevicesActivated` event and invokes the virtual `Initialize()` method on `Device` in a separate thread. This allows all devices to concurrently initialize in parallel threads.
The main task that should be undertaken in the `Initialize()` method for any 3rd party device class, it to begin communication with the device via its API. Ideally, no class that communicates with a 3rd party device outside the program should attempt to start communicating before this point.
### Example (from `PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoSparkCodec`)
```cs
public override void Initialize()
{
var socket = Communication as ISocketStatus;
if (socket != null)
{
socket.ConnectionChange += new EventHandler<GenericSocketStatusChageEventArgs>(socket_ConnectionChange);
}
Communication.Connect();
CommunicationMonitor.Start();
const string prefix = "xFeedback register ";
CliFeedbackRegistrationExpression =
prefix + "/Configuration" + Delimiter +
prefix + "/Status/Audio" + Delimiter +
prefix + "/Status/Call" + Delimiter +
prefix + "/Status/Conference/Presentation" + Delimiter +
prefix + "/Status/Cameras/SpeakerTrack" + Delimiter +
prefix + "/Status/RoomAnalytics" + Delimiter +
prefix + "/Status/RoomPreset" + Delimiter +
prefix + "/Status/Standby" + Delimiter +
prefix + "/Status/Video/Selfview" + Delimiter +
prefix + "/Status/Video/Layout" + Delimiter +
prefix + "/Status/Video/Input/MainVideoMute" + Delimiter +
prefix + "/Bookings" + Delimiter +
prefix + "/Event/CallDisconnect" + Delimiter +
prefix + "/Event/Bookings" + Delimiter +
prefix + "/Event/CameraPresetListUpdated" + Delimiter +
prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter;
}
```
## The goal