public TraficLight() { underlying = new Timer(TimeSpan.FromSeconds(5)); LightColor = Color.Red; underlying.AddEvent(() => { if (LightColor == Color.Red) { LightColor = Color.Green; } else if (LightColor == Color.Green) { LightColor = Color.Yellow; } else { LightColor = Color.Red; } if (LightChanged != null) { LightChanged.Invoke(this, EventArgs.Empty); } }); underlying.Start(); }
/// <summary> /// begins as if was in durationGreen state initially /// /// this method is += subscribed to the Timer's published ⚡ Elapsed event /// (internally in the same class scope that Timer is declared) /// </summary> void OnPulseTickEvent(object source, ElapsedEventArgs e) { _secondsElapsedInCycle += 1; //todo: proper state machine that correctly separates four states for three colors... //right now is weak design, as relies on symmetry between this function on SetNextLightColor(); //check if light changes if ((Light == ConsoleColor.Green && _secondsElapsedInCycle == _durationGreen) || (Light == ConsoleColor.DarkYellow && _secondsElapsedInCycle == _durationAmber) || (Light == ConsoleColor.Red && _secondsElapsedInCycle == _durationRedAll + _durationRedJustThis)) { //switch _secondsElapsedInCycle = 0; SetNextLightColor(); Console.ForegroundColor = Light; Console.WriteLine($"current light color is ... {Light}"); // I wanna publish or emit or raise an event here... hmm... // so how about ... this! LightChanged?.Invoke(Light); } }
/// <summary> /// Invoke listeners /// </summary> /// <param name="sender"> Initializer of event </param> /// <param name="eventArgs"> Event arguments </param> protected virtual void OnLightChange(object sender, LightArgs eventArgs) { LightChanged?.Invoke(sender, eventArgs); }
//Grobal private void LightChagne(object sender, RoutedEventArgs e) => LightChanged?.Invoke(null, null);