From 6d7e062c92b502026ca387f031c945b899599a28 Mon Sep 17 00:00:00 2001 From: "Reto Tschofenig, ODT Informatik GmbH" Date: Wed, 7 Dec 2016 10:51:39 +0100 Subject: [PATCH] story --- .gitignore | 6 ++ README.md | 20 ++++++ elm-package.json | 23 +++++++ src/Story.elm | 137 +++++++++++++++++++++++++++++++++++++++++ tests/.gitignore | 1 + tests/Main.elm | 18 ++++++ tests/StoryTest.elm | 109 ++++++++++++++++++++++++++++++++ tests/elm-package.json | 20 ++++++ 8 files changed, 334 insertions(+) create mode 100644 elm-package.json create mode 100644 src/Story.elm create mode 100644 tests/.gitignore create mode 100644 tests/Main.elm create mode 100644 tests/StoryTest.elm create mode 100644 tests/elm-package.json diff --git a/.gitignore b/.gitignore index a594364..34ee641 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,9 @@ elm-stuff/ # elm-repl generated files repl-temp-* +# Distribution +dist/ +# Dependency directories +node_modules +# Desktop Services Store on macOS +.DS_Store diff --git a/README.md b/README.md index 3ee3e73..a422ec2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,22 @@ # elm-vst VST Visualisierungs-Simulations-Tool + +Experiment zur Portierung von odt-vst nach Elm. + +- [Simulation](#simulation) +- [Visualisierung](#visualisierung) +- [Story](#story) +- [SubTitles](#subtitles) + +## Simulation +Simulation von Maschinen, Sensoren, Kabeln und Datenpaketen. +Erkennen von Nadelohren. + +## Visualisierung +SVG or 3D? + +## Story +Definition der Ereignisse, die in der Simulation im Laufe der Zeit passieren. + +## SubTitles +Untertitel diff --git a/elm-package.json b/elm-package.json new file mode 100644 index 0000000..919b035 --- /dev/null +++ b/elm-package.json @@ -0,0 +1,23 @@ +{ + "version": "0.2.0", + "summary": "VST - Visualisierungs-Simulations-Tool", + "repository": "https://github.com/odtch/elm-vst.git", + "license": "", + "source-directories": [ + ".", + "src/" + ], + "exposed-modules": [], + "dependencies": { + "elm-community/linear-algebra": "1.0.0 <= v < 2.0.0", + "elm-community/webgl": "1.0.0 <= v < 2.0.0", + "elm-lang/animation-frame": "1.0.1 <= v < 2.0.0", + "elm-lang/core": "5.0.0 <= v < 6.0.0", + "elm-lang/html": "2.0.0 <= v < 3.0.0", + "elm-lang/http": "1.0.0 <= v < 2.0.0", + "elm-lang/svg": "2.0.0 <= v < 3.0.0", + "elm-lang/virtual-dom": "2.0.1 <= v < 3.0.0", + "mgold/elm-animation": "1.0.5 <= v < 2.0.0" + }, + "elm-version": "0.18.0 <= v < 0.19.0" +} diff --git a/src/Story.elm b/src/Story.elm new file mode 100644 index 0000000..7c2953f --- /dev/null +++ b/src/Story.elm @@ -0,0 +1,137 @@ +module Story exposing (..) + +import Time exposing (Time) + + +type Action msg + = Wait Time + | Send msg + + +type alias Event msg = + { occursAt : Time + , msg : msg + } + + +type alias Story msg = + { events : List (Event msg) } + + +type alias Player msg = + { story : Story msg + , time : Time + , paused : Bool + , speed : Float + } + + +create : List (Action msg) -> Story msg +create actions = + let + ( time, events ) = + List.foldl + (\action ( time, events ) -> + case action of + Wait delay -> + ( time + delay, events ) + + Send msg -> + ( time, events ++ [ { occursAt = time, msg = msg } ] ) + ) + ( 0, [] ) + actions + in + { events = events + } + + +messagesBetween : Time -> Time -> Story msg -> List msg +messagesBetween start end story = + List.map (\event -> event.msg) <| List.filter (\event -> occursIn start end event) story.events + + +occursIn : Time -> Time -> Event msg -> Bool +occursIn start end event = + (start <= event.occursAt) && (event.occursAt < end) + + +start : Story msg -> Player msg +start story = + { story = story + , time = 0 + , paused = False + , speed = 1 + } + + +setPaused : Bool -> Player msg -> Player msg +setPaused paused player = + { player | paused = paused } + + +setSpeed : Float -> Player msg -> Player msg +setSpeed speed player = + if (speed <= 0 || 100 < speed) then + Debug.crash "speed out of range" + else + { player | speed = speed } + + +tick : Time -> Player msg -> ( Player msg, List msg ) +tick time player = + if (player.paused) then + ( player, [] ) + else + let + newtime = + player.time + time * player.speed + in + ( { player + | time = newtime + } + , messagesBetween player.time newtime player.story + ) + + + +-- +-- +-- tick : Time -> (msg -> model -> ( model, Cmd msg )) -> Player msg -> model -> ( Player msg, model, Cmd msg ) +-- tick time update player model = +-- if (player.paused) then +-- ( player, model, Cmd.none ) +-- else +-- let +-- newtime = +-- player.time + time * player.speed +-- +-- events = +-- List.filter (occursIn player.time newtime) player.story.events +-- +-- ( newmodel, msg ) = +-- executeEvents update events model +-- in +-- ( { player +-- | time = newtime +-- } +-- , newmodel +-- , msg +-- ) +-- +-- +-- executeEvents : (msg -> model -> ( model, Cmd msg )) -> List (Event msg) -> model -> ( model, Cmd msg ) +-- executeEvents update events model = +-- List.foldl +-- (\event ( premodel, precmd ) -> +-- case event of +-- Empty message -> +-- ( premodel, precmd ) +-- +-- Soon time data -> +-- update data.msg premodel +-- ) +-- ( model, Cmd.none ) +-- events +-- +-- diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..aee9810 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1 @@ +/elm-stuff/ diff --git a/tests/Main.elm b/tests/Main.elm new file mode 100644 index 0000000..b08644d --- /dev/null +++ b/tests/Main.elm @@ -0,0 +1,18 @@ +port module Main exposing (..) + +import Test exposing (..) +import Test.Runner.Node exposing (run, TestProgram) +import Json.Encode exposing (Value) +import StoryTest + + +main : TestProgram +main = + run emit <| + describe "VST - Story Test Suite" + [ --Tests.all, + StoryTest.all + ] + + +port emit : ( String, Value ) -> Cmd msg diff --git a/tests/StoryTest.elm b/tests/StoryTest.elm new file mode 100644 index 0000000..47fdfce --- /dev/null +++ b/tests/StoryTest.elm @@ -0,0 +1,109 @@ +module StoryTest exposing (..) + +import Test exposing (..) +import Time exposing (..) +import Expect +import Fuzz exposing (list, int, tuple, string) +import String +import Story exposing (Story) + + +story : Story String +story = + Story.create + [ Story.Send "A" + , Story.Wait <| 1 * second + , Story.Send "B" + , Story.Send "C" + , Story.Wait <| 2 * second + , Story.Send "D" + ] + + +eventsToString : List (Story.Event String) -> String +eventsToString events = + List.foldl + (\event text -> + (if (String.length text == 0) then + "" + else + text ++ ", " + ) + ++ "at " + ++ (toString <| inSeconds event.occursAt) + ++ " " + ++ event.msg + ) + "" + events + + +messagesToString : List String -> String +messagesToString messages = + List.foldl + (\message text -> + (if (String.length text == 0) then + "" + else + text ++ ", " + ) + ++ message + ) + "" + messages + + +runPlayer : Time -> Story String -> String +runPlayer stepTime story = + let + stepCount = + round <| (second * 6.0) / stepTime + + ticks = + List.repeat stepCount stepTime + + player = + Story.start story + + ( newplayer, text ) = + (List.foldr + (\time ( player, text ) -> + let + ( newplayer, messages ) = + Story.tick time player + in + ( newplayer, text ++ (messagesToString messages) ++ " | " ) + ) + ( player, "" ) + ticks + ) + in + text + + +all : Test +all = + describe "Story Test" + [ test "all events" <| + \() -> Expect.equal (eventsToString story.events) "at 0 A, at 1 B, at 1 C, at 3 D" + , test "events 0 - 1" <| + \() -> Expect.equal (messagesToString (Story.messagesBetween (0 * second) (1 * second) story)) "A" + , test "events 0 - 2" <| + \() -> Expect.equal (messagesToString (Story.messagesBetween (0 * second) (2 * second) story)) "A, B, C" + , test "events 0 - 4" <| + \() -> Expect.equal (messagesToString (Story.messagesBetween (0 * second) (4 * second) story)) "A, B, C, D" + , test "events 1 - 2" <| + \() -> Expect.equal (messagesToString (Story.messagesBetween (1 * second) (2 * second) story)) "B, C" + , test "events 1 - 4" <| + \() -> Expect.equal (messagesToString (Story.messagesBetween (1 * second) (4 * second) story)) "B, C, D" + , test "events 3 - 4" <| + \() -> Expect.equal (messagesToString (Story.messagesBetween (3 * second) (4 * second) story)) "D" + , test "events 4 - 5" <| + \() -> Expect.equal (messagesToString (Story.messagesBetween (4 * second) (5 * second) story)) "" + , test "player 1s" <| + \() -> Expect.equal (runPlayer (1 * second) story) "A | B, C | | D | | | " + , test "player 0.5s" <| + \() -> Expect.equal (runPlayer (0.5 * second) story) "A | | B, C | | | | D | | | | | | " + , test "player 2s" <| + \() -> Expect.equal (runPlayer (2 * second) story) "A, B, C | D | | " + ] diff --git a/tests/elm-package.json b/tests/elm-package.json new file mode 100644 index 0000000..ea659db --- /dev/null +++ b/tests/elm-package.json @@ -0,0 +1,20 @@ +{ + "version": "1.0.0", + "summary": "Sample Elm Test", + "repository": "https://github.com/user/project.git", + "license": "BSD-3-Clause", + "source-directories": [ + ".", + "../src" + ], + "exposed-modules": [], + "dependencies": { + "elm-community/json-extra": "2.0.0 <= v < 3.0.0", + "elm-lang/html": "2.0.0 <= v < 3.0.0", + "mgold/elm-random-pcg": "4.0.2 <= v < 5.0.0", + "elm-lang/core": "5.0.0 <= v < 6.0.0", + "elm-community/elm-test": "3.0.0 <= v < 4.0.0", + "rtfeldman/node-test-runner": "3.0.0 <= v < 4.0.0" + }, + "elm-version": "0.18.0 <= v < 0.19.0" +}