Files
2026-04-17 14:55:32 -04:00

8.1 KiB
Raw Permalink Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
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
2026-04-16T03:15:09.204079+00:00 Qwen/Qwen3-Coder-Next-FP8 1 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: ClockSyncProfiles 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.