Documentation
¶
Overview ¶
Package switchserver is the Matter Switch cluster server (0x003B): a semantic port of matter.js SwitchBaseServer (packages/node/src/behaviors/switch/SwitchServer.ts at 862ad75f), the server that derives every Switch event from one stream of switch positions. The directory is cluster/switch; `switch` is a Go keyword, so the package is named switchserver.
The cluster's identity is its generated definition (cluster/spec/switchcluster, ADR 0013): ids, revision, the feature bits LS, MS, MSR, MSL, MSM and AS (Config.Features, matter.js SwitchServer.with(...)), the attribute and event lists the selection yields, the write statuses and the event payloads. The behaviour is matter.js's:
- Server.SetRawPosition is matter.js `rawPosition`: debounced by the debounce delay when one is set, decided at once otherwise (#handleRawPosition :128-151, #handleDebouncedPosition :153-157).
- Server.SetCurrentPosition is a position the host debounced itself, matter.js's write of `currentPosition` (#handleWrittenPosition :177-190).
- Both end in the same decision (#decidePosition :230-326): the events of a latching switch (SwitchLatched), of a momentary one (InitialPress, ShortRelease, LongPress, LongRelease) and of its multi-press sequences (MultiPressOngoing, MultiPressComplete), with the long-press and multi-press timers on clock.Clock.
- The decided events and CurrentPosition writes apply in the order the inputs occurred (the result queue, #queueEvent :219-227 and #applyResults :204-217).
A source that knows only gestures keeps its path: the server implements contract.SwitchEventEmitter, so a host that narrates InitialPress, ShortRelease, LongPress and LongRelease reaches the same events and moves CurrentPosition with them. Report a switch through positions or through gestures, not both — matter.js says the same of rawPosition and currentPosition (the class doc, :63-64).
Index ¶
- Constants
- Variables
- type Config
- type Feature
- type Server
- func (s *Server) CurrentPosition() uint8
- func (s *Server) Endpoint() uint16
- func (s *Server) FireInitialPress(newPosition uint8)
- func (s *Server) FireLongPress(newPosition uint8)
- func (s *Server) FireLongRelease(previousPosition uint8)
- func (s *Server) FireShortRelease(previousPosition uint8)
- func (s *Server) RawPosition() uint8
- func (s *Server) ResetState()
- func (s *Server) SetAttributes(values map[uint32]any) error
- func (s *Server) SetCurrentPosition(position uint8) error
- func (s *Server) SetDebounceDelay(d time.Duration)
- func (s *Server) SetEndpoint(ep uint16)
- func (s *Server) SetLongPressDelay(d time.Duration)
- func (s *Server) SetMatterEventEmitter(emitter contract.EventEmitter)
- func (s *Server) SetMultiPressDelay(d time.Duration)
- func (s *Server) SetRawPosition(position uint8) error
Constants ¶
const ( FeatureLS = swdef.FeatureLatchingSwitch FeatureMS = swdef.FeatureMomentarySwitch FeatureMSR = swdef.FeatureMomentarySwitchRelease FeatureMSL = swdef.FeatureMomentarySwitchLongPress FeatureMSM = swdef.FeatureMomentarySwitchMultiPress FeatureAS = swdef.FeatureActionSwitch )
FeatureMap bits as Feature values for Config.Features. The definition's conformance holds: exactly one of LS and MS; MSR only without AS; MSL with MSR or AS; MSM with MSR, and mandatory with AS.
const ( // DefaultLongPressDelay is DEFAULT_LONG_PRESS_DELAY, Seconds(2) (:15). DefaultLongPressDelay = 2 * time.Second // DefaultMultiPressDelay is DEFAULT_MULTIPRESS_DELAY, Millis(300) (:14). DefaultMultiPressDelay = 300 * time.Millisecond // DefaultNumberOfPositions is the State default (:474). DefaultNumberOfPositions uint8 = 2 // DefaultMultiPressMax is the State default (:475). DefaultMultiPressMax uint8 = 2 )
The defaults of matter.js's added state (SwitchServer.ts:14-15, :465-475).
const ClusterID = swdef.ClusterID
ClusterID is the Switch cluster id (0x003B).
Variables ¶
var ErrConfig = errors.New("switch: configuration outside the cluster's model")
ErrConfig reports a configuration the cluster's model refuses.
var ErrPositionOutOfRange = errors.New("switch: position outside 0..NumberOfPositions-1")
ErrPositionOutOfRange reports a position outside 0..NumberOfPositions-1. The error Server.SetRawPosition and Server.SetCurrentPosition return wraps it and answers CONSTRAINT_ERROR (matter.js #assertPositionInRange :122-126).
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Features is the FeatureMap selection; the definition's conformance
// is checked.
Features Feature
// Endpoint is the endpoint the events are addressed to. The bridge
// also sets it at assembly ([Server.SetEndpoint]).
Endpoint uint16
// NumberOfPositions is the attribute; 0 is 2 (:474).
NumberOfPositions uint8
// MultiPressMax is the attribute (MSM only); 0 is 2 (:475).
MultiPressMax uint8
// CurrentPosition is the position the switch starts in; rawPosition
// starts there too (initialize :81-82).
CurrentPosition uint8
// MomentaryNeutralPosition is the position a momentary switch rests
// in (:471, default 0).
MomentaryNeutralPosition uint8
// DebounceDelay debounces [Server.SetRawPosition]; 0 decides a raw
// position at once (debounceDelay, optional, :462).
DebounceDelay time.Duration
// LongPressDelay is the hold that makes a press long (MSL); 0 is
// [DefaultLongPressDelay] (:465).
LongPressDelay time.Duration
// MultiPressDelay is the release that ends a multi-press sequence
// (MSM); 0 is [DefaultMultiPressDelay] (:468).
MultiPressDelay time.Duration
// Clock runs the debounce, long-press and multi-press timers; nil is
// [clock.System].
Clock clock.Clock
// DataVersion is an optional host-owned tracker.
DataVersion *cluster.DataVersionTracker
}
Config carries the construction parameters. The zero value of a delay or a count is matter.js's default.
type Server ¶
Server is the Switch server. It implements contract.ClusterServer through the generated spec.Server it embeds (reads, the read-only write answers, the lists, the data version and the change notification), contract.EventReceiver, contract.SwitchEventEmitter and contract.SwitchPositionSink.
Locking. Every input — a position, a gesture, a timer — is decided under one mutex at the moment it occurs, as matter.js decides its input reactors synchronously and unlocked (initialize :88-94). The decided events and CurrentPosition writes leave the server in that order through one outbox, delivered with no lock held, so an event emitter or a change listener may read the server. matter.js's switch state lock — the transaction lock its #applyQueuedResults reactor and resetState wait for (:95, :104-105) — is the [Server.hold] seam: while it is held, queued results wait and Server.ResetState waits.
func New ¶
New builds a Switch server. The feature selection is held to the definition's conformance, NumberOfPositions and MultiPressMax to their "min 2", CurrentPosition and MomentaryNeutralPosition to the positions. Mirrors matter.js SwitchServer.ts:80-96 (initialize): rawPosition and the decided position start at CurrentPosition.
func (*Server) CurrentPosition ¶
CurrentPosition returns the CurrentPosition attribute as last written.
func (*Server) FireInitialPress ¶
FireInitialPress implements contract.SwitchEventEmitter: InitialPress, then CurrentPosition moves to newPosition (when it is a position).
func (*Server) FireLongPress ¶
FireLongPress implements contract.SwitchEventEmitter: LongPress (MSL); CurrentPosition stays.
func (*Server) FireLongRelease ¶
FireLongRelease implements contract.SwitchEventEmitter: LongRelease (MSL), then CurrentPosition returns to the neutral position.
func (*Server) FireShortRelease ¶
FireShortRelease implements contract.SwitchEventEmitter: ShortRelease (MSR), then CurrentPosition returns to the neutral position.
func (*Server) RawPosition ¶
RawPosition returns matter.js's rawPosition: the last raw position reported, debounced or not.
func (*Server) ResetState ¶
func (s *Server) ResetState()
ResetState starts a clean cycle, mainly for automated tests: it waits for the switch state lock, then drops pending debounced positions, timers and results not applied yet, so nothing from before the reset is reported or written after it, and continues from the current position. Mirrors matter.js SwitchServer.ts:98-119.
func (*Server) SetAttributes ¶ added in v0.10.0
SetAttributes implements spec.AttributeSetter: CurrentPosition is the host's write of the position it debounced itself (Server.SetCurrentPosition — matter.js's write of state.currentPosition, which the press logic and its events follow, SwitchServer.ts:177-190); NumberOfPositions and MultiPressMax are the configuration's (spec.ErrNotHeld).
func (*Server) SetCurrentPosition ¶
SetCurrentPosition reports a position the host debounced itself, matter.js's write of `state.currentPosition` (#handleWrittenPosition SwitchServer.ts:177-190, the currentPosition$Changed reactor :91). The written position supersedes position writes still queued, not the events queued before it. A position outside the range is refused with CONSTRAINT_ERROR (:86); an unchanged one changes nothing.
func (*Server) SetDebounceDelay ¶
SetDebounceDelay sets the debounce delay of Server.SetRawPosition; 0 decides a raw position at once (matter.js state.debounceDelay, :462).
func (*Server) SetEndpoint ¶
SetEndpoint sets the endpoint the events are addressed to; the bridge calls it at assembly.
func (*Server) SetLongPressDelay ¶
SetLongPressDelay sets the hold that makes a press long; 0 is DefaultLongPressDelay (state.longPressDelay, :465). A timer already running keeps its delay.
func (*Server) SetMatterEventEmitter ¶
func (s *Server) SetMatterEventEmitter(emitter contract.EventEmitter)
SetMatterEventEmitter implements contract.EventReceiver.
func (*Server) SetMultiPressDelay ¶
SetMultiPressDelay sets the release that ends a multi-press sequence; 0 is DefaultMultiPressDelay (state.multiPressDelay, :468).
func (*Server) SetRawPosition ¶
SetRawPosition reports the switch's raw position, matter.js `state.rawPosition`: debounced by the debounce delay when one is set (SwitchServer.ts:128-151, the rawPosition$Changed reactor :90). A position outside the range is refused with CONSTRAINT_ERROR (#assertPositionInRange, the rawPosition$Changing reactor :85); an unchanged one changes nothing, as an unchanged state value fires no $Changed event in matter.js.