Files
DP44/enriched-qwen3-coder-next/Common/DTS.Common/Classes/ClockSync.md

116 lines
8.1 KiB
Markdown
Raw Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- Common/DTS.Common/Classes/ClockSync/IClockSyncProfile.cs
- Common/DTS.Common/Classes/ClockSync/ClockSyncProfile.cs
- Common/DTS.Common/Classes/ClockSync/ClockSyncProfileConverter.cs
- Common/DTS.Common/Classes/ClockSync/ClockSyncProfileCollection.cs
generated_at: "2026-04-16T03:15:09.204079+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "e412b56844d5af45"
---
# ClockSync
## Documentation: Clock Sync Profile Module
### 1. Purpose
This module defines and manages clock synchronization profiles for the DTS system, enabling configuration of different master clock input sources (e.g., PTP IEEE 1588, IRIG-B, GPS, 1PPS). It provides a singleton collection (`ClockSyncProfileCollection`) that loads profile definitions from an XML file (`ClockSyncProfiles.xml`), falling back to a default set if the file is missing. Profiles are represented by the `ClockSyncProfile` class, which implements the `IClockSyncProfile` interface and supports metadata-driven initialization from an enum (`ClockSyncProfileDefaults`). The module also includes a type converter (`ClockSyncProfileConverter`) for UI integration (e.g., property grids), ensuring only visible profiles are exposed and sorted by display order.
---
### 2. Public Interface
#### `IClockSyncProfile` (Interface)
- **`int ProfileId { get; set; }`**
Unique integer identifier for the profile.
- **`string ProfileName { get; set; }`**
Human-readable name of the profile (e.g., `"PTP IEEE 1588"`).
- **`string ProfileDesc { get; set; }`**
Description of the profiles behavior or purpose.
- **`int DisplayOrder { get; set; }`**
Integer priority for ordering profiles in UI (lower values appear first).
- **`bool Visible { get; set; }`**
Flag indicating whether the profile should be shown in UI (e.g., property grids).
- **`DASRestriction[] FilterRestrictions { get; set; }`**
Array of restrictions (of type `DASRestriction`) applied to the profile; used to filter applicable DAS configurations.
#### `ClockSyncProfile` (Concrete Implementation)
- **`ClockSyncProfile()`**
Parameterless constructor for deserialization.
- **`ClockSyncProfile(int profileId, string profileName, string profileDesc, int displayOrder, bool visible, DASRestriction[] filterRestrictions)`**
Initializes a profile with explicit values via `Initialize()`.
- **`ClockSyncProfile(ClockSyncProfileCollection.ClockSyncProfileDefaults defaults, DASRestriction[] restrictions)`**
Initializes a profile by extracting metadata (name, description, order, visibility) from the `ClockSyncProfileDefaults` enum using reflection on `[Display]` and `[Browsable]` attributes, then calls `Initialize()`.
- **`override string ToString()`**
Returns `ProfileName`.
#### `ClockSyncProfileConverter` (Type Converter)
- **`ClockSyncProfile[] Values { get; }`**
Lazily-initialized array of *visible* profiles from the singleton collection, sorted by `DisplayOrder`. Thread-safe via `lock`.
- **`override bool CanConvertFrom(...)`**
Returns `true` if `sourceType == typeof(string)` (enables string-to-profile conversion by name).
- **`override object ConvertFrom(...)`**
Converts a string (profile name) to a `ClockSyncProfile` instance by matching `ProfileName` in `Values`. Returns `null` if no match.
- **`override bool GetStandardValuesSupported(...)`**
Returns `true` (indicates standard values are available).
- **`override bool GetStandardValuesExclusive(...)`**
Returns `true` (indicates only standard values are valid; no free-text input).
- **`override StandardValuesCollection GetStandardValues(...)`**
Returns a `StandardValuesCollection` containing *all* profiles from the singleton collection (including non-visible ones).
#### `ClockSyncProfileCollection` (Singleton Collection)
- **`static ClockSyncProfileCollection GetCollection()`**
Thread-safe singleton accessor. Loads profiles from `ClockSyncProfiles.xml` (creating it with defaults if missing).
- **`ClockSyncProfile GetClockSyncProfile(string s)`**
Returns the first profile matching `ProfileName == s`. If no match, returns the profile with `ProfileId == 0` (typically `"None"`). If neither exists, returns the first item in the collection.
- **Constants**:
- `NONE_NAME`, `PTPIEEE1588_NAME`, `IRIGB1PPS_NAME`, `GPS1PPS_NAME`, `IRIGB_NAME`, `_1PPS_NAME`
Hardcoded string constants for profile names (e.g., `"PTP IEEE 1588"`).
- **`ClockSyncProfileDefaults` Enum**:
Defines default profile types with `[Display]` and `[Browsable]` attributes:
- `None` (ID=0)
- `PTPIEEE1588` (ID=1)
- `IRIGB1PPS` (ID=2)
- `GPS1PPS` (ID=4)
- `IRIGB` (ID=8)
- `_1PPS` (ID=16)
Values use bit-shifted powers of two (e.g., `1 << 0`, `1 << 1`), but IDs are cast to `int` directly in `GetProfileInfo()`.
---
### 3. Invariants
- **Singleton Consistency**: `GetCollection()` always returns the same instance after first initialization.
- **Profile Visibility Filtering**: `ClockSyncProfileConverter.Values` only includes profiles where `Visible == true`.
- **Display Order Sorting**: `ClockSyncProfileConverter.Values` is sorted ascending by `DisplayOrder` (using `int.MaxValue` as fallback for missing order).
- **Fallback Profile Selection**: `GetClockSyncProfile(string)` prioritizes exact name match, then `ProfileId == 0`, then first item.
- **XML File Handling**: `ClockSyncProfiles.xml` is auto-generated with defaults if missing; existing file is never overwritten.
- **Enum Metadata Dependency**: `ClockSyncProfile`s enum-based constructor relies on `[Display]` and `[Browsable]` attributes being present on `ClockSyncProfileDefaults` members. Missing attributes cause runtime exceptions (e.g., `IndexOutOfRangeException` on `valueAttributes[0]`).
---
### 4. Dependencies
- **Internal Dependencies**:
- `DTS.Common.Classes.DSP.DASRestriction` (used in `FilterRestrictions`).
- `System.ComponentModel.DataAnnotations` (for `[Display]`, `[Browsable]`).
- `System.Xml.Serialization` (for XML serialization/deserialization).
- `System.Collections.ObjectModel.Collection<T>` (base class).
- **External Dependencies**:
- `ClockSyncProfileCollection` depends on `DASRestriction` type (defined elsewhere in `DTS.Common`).
- `ClockSyncProfileConverter` depends on `ClockSyncProfileCollection` (singleton access).
- **Depended Upon By**:
- UI components (e.g., property grids) via `ClockSyncProfileConverter`.
- Other modules requiring clock sync configuration (e.g., DSP configuration logic).
---
### 5. Gotchas
- **Enum ID Mismatch**: `ClockSyncProfileDefaults` uses bit-shifted values (e.g., `1 << 0 = 1`, `1 << 1 = 2`), but `GetProfileInfo()` casts the enum value directly to `int` for `profileId`. This means `IRIGB1PPS` has `ProfileId = 2`, not `1`. Ensure downstream logic does not assume sequential IDs.
- **Attribute Dependency**: If `[Display]` or `[Browsable]` attributes are missing on a `ClockSyncProfileDefaults` member, `GetProfileInfo()` throws `IndexOutOfRangeException` (accessing `valueAttributes[0]` without null checks).
- **Thread-Safe Lazy Initialization**: `ClockSyncProfileConverter.Values` uses double-checked locking but reinitializes `_values` only once per app domain. Subsequent modifications to the collection (e.g., via `GetCollection().Add(...)`) will *not* update `_values` until the converter is recreated.
- **Non-Visible Profiles in StandardValues**: `GetStandardValues()` returns *all* profiles (including non-visible ones), while `Values` returns only visible ones. This inconsistency may confuse consumers expecting uniform filtering.
- **Hardcoded XML Filename**: `CLOCKSYNC_PROFILE_XML_FILE = "ClockSyncProfiles.xml"` is hardcoded; no configuration override is provided.
- **No Validation on `FilterRestrictions`**: `FilterRestrictions` is a `DASRestriction[]` with no null-checking or validation in constructors. Passing `null` may cause `NullReferenceException` downstream.
- **No Profile Modification Support**: The collection is read-only after initialization (via `Collection<T>` base). Adding/removing profiles at runtime requires direct manipulation of `Items`, which bypasses validation.
None identified beyond these.