Files
DP44/enriched-qwen3-coder-next/Common/DTS.Common/Classes/ClockSync.md
2026-04-17 14:55:32 -04:00

116 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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.