Można to zrobić na różne sposoby. Każdy ma swoje zalety. Dam ci trzy, które znam, z podobnym przykładem dla każdego.
1) Dodaj wejście giełdowy czasu
Jedno można zrobić, to dodać razem z wejściami programu. Przykładem malutkim programem używając aktualnego czasu co drugi losową liczbę:
import Time
import Time (Time, second)
import Text (asText)
import Mouse
import Signal
import Signal (Signal, (<~), (~))
import Random
import Random (Seed)
import Graphics.Element (Element)
randomInt : Seed -> Int
randomInt seed = seed |> (Random.generate <| Random.int 1 10) |> fst
otherInput : Signal (Int,Int)
otherInput = Mouse.position
timeSeed : Signal Seed
timeSeed = Random.initialSeed << round <~ Time.every second
inputs : Signal (Seed,(Int,Int))
inputs = (,) <~ timeSeed ~ otherInput
update : (Seed, (Int,Int)) -> (Int,Int) -> (Int,Int)
update (seed,(x,y)) (x',y') =
let num = randomInt seed
in (x-x'-num,y'-y+num) -- this update function is nonsense
main : Signal Element
main = asText <~ Signal.foldp update (0,0) inputs
Jeśli potrzebują czasu jako wejście i tak, i spróbować swoich innych wejść w oparciu o ten czas, to najprostszy sposób. (Jeśli używałeś Time.fps
do tego użyć Time.timestamp
aby uzyskać aktualny czas z nim)
2) przy starcie z sygnałem
Jeśli nie zwykle potrzebują czasu, jako wkład do twojego programu, poprzednie rozwiązanie nie jest idealne. Możesz preferować inicjalizację stanu programu z czasem rozpoczęcia programu i nie musisz ignorować znacznika czasu przez resztę czasu działania programu.
Najprawdopodobniej najłatwiej zrobić to z signal-extra package *. Użyj Signal.Time.startTime
, aby uzyskać sygnał, który nie zaznacza, ale ma tylko czas rozpoczęcia programu jako wartość początkową. Użyj wartości Signal.Extra.foldp'
, aby użyć początkowej wartości swoich danych wejściowych.
import Time
import Time (Time, second)
import Text (asText)
import Mouse
import Signal
import Signal (Signal, (<~), (~))
import Random
import Random (Seed)
import Graphics.Element (Element)
import Signal.Extra as SignalE
import Signal.Time as Time
randomInt : Seed -> (Int,Seed)
randomInt seed = (Random.generate <| Random.int 1 10) |> fst
otherInput : Signal (Int,Int)
otherInput = Mouse.position
startTimeSeed : Signal Seed
startTimeSeed = Random.initialSeed << round <~ Time.startTime
inputs : Signal (Seed,(Int,Int))
inputs = (,) <~ startTimeSeed ~ otherInput
update (x,y) (seed,(x',y')) =
let (num,seed') = randomInt seed
in (seed',(x-x'-num,y'-y+num))
main : Signal Element
main = asText <~ SignalE.foldp' (snd >> update) identity inputs
* Mogę być stronniczy, ponieważ jestem autorem połączonego pakietu. Ale nie znam innych pakietów oferujących tę samą funkcjonalność.
3) Przy starcie z portem
Jeśli okaże poprzednie rozwiązanie niezadowalające, ponieważ masz to nie zmienia Signal
dodać do wejścia, to rozwiązanie jest dla Ciebie. Tutaj używamy JavaScript interop, aby uzyskać czas uruchomienia programu, a Wiąz zaakceptuje go jako stałą wartość (nr Signal
). Kod wiązów wygląda następująco:
import Time
import Time (Time, second)
import Text (asText)
import Mouse
import Signal (Signal, (<~))
import Random
import Random (Seed)
import Graphics.Element (Element)
port startTime : Float
randomInt : Seed -> (Int,Seed)
randomInt seed = (Random.generate <| Random.int 1 10) |> fst
startTimeSeed : Seed
startTimeSeed = Random.initialSeed <| round startTime
update (x,y) (seed,(x',y')) =
let (num,seed') = randomInt seed
in (seed',(x-x'-num,y'-y+num))
main : Signal Element
main = asText <~ Signal.foldp update (startTimeSeed, (0,0)) Mouse.position
Co tu jest wadą? Musisz napisać trochę kodu JavaScript. Zamiast standardowego
<script>Elm.fullscreen(Elm.<YourModule>)</script>
, trzeba coś takiego w pliku html:
<script>Elm.fullscreen(Elm.<YourModule>, {startTime: Date.now()})</script>
Jeśli wybierzesz ten sposób, być może jest to dobry pomysł, aby wykorzystać liczbę losową z JavaScript jako początkowy nasionko. Czytałem, że jest to bardziej bezpieczne kryptograficznie (zrzeczenie się: nie wiem zbyt wiele o krypto). Więc masz port aRandomNumber : Int
i {aRandomNumber: Math.floor((Math.random() - 0.5) * 4294967295)}
.
Omawiamy to teraz na liście mailingowej Elm: https://groups.google.com/d/msg/elm-discuss/ilDp3-ekJ98/cA-oiAAzWskJ –