|
import kotlin.properties.ReadOnlyProperty |
|
import kotlin.reflect.KProperty |
|
|
|
interface AnimatedSlide<in T, out Slide> : ReadOnlyProperty<T, Slide> { |
|
val currentSlide: Slide |
|
|
|
override fun getValue(thisRef: T, property: KProperty<*>) = currentSlide |
|
|
|
class VarargImpl<in T, out Slide>(private vararg val slides: Slide) : AnimatedSlide<T, Slide> { |
|
private var i = 0 |
|
|
|
override val currentSlide: Slide get() = slides[i].also { i = (i + 1) % slides.size } |
|
} |
|
} |
|
|
|
interface TrafficLight { |
|
|
|
val currentSignal: Signal |
|
|
|
fun iterate() |
|
|
|
fun show() |
|
|
|
abstract class Abstract(initialSignal: Signal) : TrafficLight { |
|
final override var currentSignal: Signal = initialSignal |
|
private set |
|
|
|
override fun iterate() { |
|
currentSignal = currentSignal.next |
|
} |
|
} |
|
|
|
abstract class ConsoleWriter(initialSignal: Signal) : Abstract(initialSignal) { |
|
override fun show() = currentSignal.show() |
|
} |
|
|
|
interface Signal { |
|
|
|
val next: Signal |
|
|
|
fun show() |
|
|
|
abstract class Abstract(private val getNext: () -> Signal) : Signal { |
|
override val next: Signal get() = getNext() |
|
} |
|
|
|
abstract class ConsoleWriter( |
|
private val text: String, |
|
next: () -> ConsoleWriter |
|
) : Abstract(next) { |
|
|
|
override fun show() { |
|
println(text) |
|
} |
|
} |
|
} |
|
} |
|
|
|
class CarConsoleWriterTrafficLight(initialSignal: Signal) : TrafficLight.ConsoleWriter(initialSignal) { |
|
|
|
abstract class Signal(text: String, next: () -> Signal) : TrafficLight.Signal.ConsoleWriter(text, next) // alias |
|
|
|
class GreenSignal : Signal("Green light", ::YellowSignal) |
|
class YellowSignal : Signal("Yellow light", ::RedSignal) |
|
class RedSignal : Signal("Red light", ::GreenSignal) |
|
} |
|
|
|
class PedestrianConsoleWriterTrafficLight(initialSignal: Signal) : TrafficLight.ConsoleWriter(initialSignal) { |
|
|
|
abstract class Signal(next: () -> Signal) : TrafficLight.Signal.Abstract(next) |
|
|
|
class GoSignal : Signal(::StopSignal) { |
|
private val currentSlide by AnimatedSlide.VarargImpl( |
|
"Green man goes this way", |
|
"Green man goes that way" |
|
) |
|
|
|
override fun show() = println(currentSlide) |
|
} |
|
|
|
class StopSignal : Signal(::GoSignal) { |
|
override fun show() = println("Red man stands still") |
|
} |
|
} |
|
|
|
fun main() { |
|
// TrafficLightIrlManager и ConsoleImpl можешь сделать сам |
|
val carTrafficLight = CarConsoleWriterTrafficLight(CarConsoleWriterTrafficLight.RedSignal()) |
|
val pedestrianTrafficLight = PedestrianConsoleWriterTrafficLight(PedestrianConsoleWriterTrafficLight.StopSignal()) |
|
|
|
println(">Подходим мы, значит, к перекрёстку\n") |
|
println(">И видим пред собой светофоры для пешехода и для машин\n") |
|
println(">Светофор для машин показывал:\n") |
|
carTrafficLight.show() |
|
println(">Светофор для пешеходов показывал:\n") |
|
pedestrianTrafficLight.show() |
|
println(">Промелькнула мысль, что странно всё это, может быть светофоры сломались\n") |
|
carTrafficLight.iterate() |
|
println(">, но в следующее мгновение всё переключилось и мы увидели, что следующие сигналы были таковые:\n") |
|
carTrafficLight.show() |
|
pedestrianTrafficLight.show() |
|
println(">И стали мы ждать зелёного сигнала для себя\n") |
|
println(">Машинам:\n") |
|
carTrafficLight.show() |
|
println(">Пешеходам:\n") |
|
pedestrianTrafficLight.show() |
|
println(">Машинам:\n") |
|
carTrafficLight.show() |
|
println(">Пешеходам:\n") |
|
pedestrianTrafficLight.show() |
|
println(">Машинам:\n") |
|
carTrafficLight.show() |
|
println(">Пешеходам:\n") |
|
pedestrianTrafficLight.show() |
|
carTrafficLight.iterate() |
|
println(">Машинам:\n") |
|
carTrafficLight.show() |
|
println(">Пешеходам:\n") |
|
pedestrianTrafficLight.show() |
|
println(">Машинам:\n") |
|
carTrafficLight.show() |
|
println(">Пешеходам:\n") |
|
pedestrianTrafficLight.show() |
|
carTrafficLight.iterate() |
|
println(">Машинам:\n") |
|
carTrafficLight.show() |
|
println(">Пешеходам:\n") |
|
pedestrianTrafficLight.show() |
|
println(">Ещё чуть-чуть, подумали мы\n") |
|
pedestrianTrafficLight.iterate() |
|
pedestrianTrafficLight.show() |
|
println(">Времени на пешеходном светофоре было указано только лишь на то чтобы дойти быстрым шагом, вот мы и поспешили\n") |
|
println(">Машинам:\n") |
|
carTrafficLight.show() |
|
println(">Пешеходам:\n") |
|
pedestrianTrafficLight.show() |
|
println(">Машинам:\n") |
|
carTrafficLight.show() |
|
println(">Пешеходам:\n") |
|
pedestrianTrafficLight.show() |
|
pedestrianTrafficLight.iterate() |
|
println(">Пешеходам:\n") |
|
pedestrianTrafficLight.show() |
|
println(">Вот мы и прошли перекрёсток\n") |
|
} |