bW9kdWxlIEZ1Y2tpblN0dXBpZERvb3IKZXhwb3J0IERvb3IsRG9vcldpdGhDbG9zZXIsRG9vcldpdGhTdG9wcGVyLERvb3JXaXRoU3RvcHBlckFuZENsb3NlcixzdGF0ZSxwdXNoLHB1bGwsc2V0c3RvcHBlcix1bnNldHN0b3BwZXIsdHVybix1bnR1cm4KYWJzdHJhY3QgQWJzdHJhY3REb29yCmFic3RyYWN0IEFic3RyYWN0RG9vcldpdGhTdG9wcGVyICZsdDs6IEFic3RyYWN0RG9vcgphYnN0cmFjdCBBYnN0cmFjdERvb3JXaXRoQ2xvc2VyICZsdDs6IEFic3RyYWN0RG9vcgpvcGVuYWJsZShkb29yOjpBYnN0cmFjdERvb3IpPSFkb29yLmtub2IudW50dXJuZWQKY2xvc2VhYmxlKGRvb3I6OkFic3RyYWN0RG9vcik9dHJ1ZQpzdGF0ZShkb29yOjpBYnN0cmFjdERvb3IpPWlmZWxzZShkb29yLmNsb3NlZCwmcXVvdDtjbG9zZWQmcXVvdDssJnF1b3Q7b3BlbmVkJnF1b3Q7KQp0eXBlIEtub2IKICB1bnR1cm5lZCA6OiBCb29sCmVuZApmdW5jdGlvbiB0dXJuKGtub2I6Oktub2IpCiAga25vYi51bnR1cm5lZD1mYWxzZQogIGtub2IKZW5kCmZ1bmN0aW9uIHVudHVybihrbm9iOjpLbm9iKQogIGtub2IudW50dXJuZWQ9dHJ1ZQogIGtub2IKZW5kCgp0eXBlIERvb3IgJmx0OzpBYnN0cmFjdERvb3IKICBjbG9zZWQgOjogQm9vbAogIGtub2IgOjogS25vYgplbmQKRG9vcihjbG9zZWQ6OkJvb2wsbGF0Y2hlZDo6Qm9vbCk9RG9vcihjbG9zZWQsS25vYihsYXRjaGVkKSkKCmZ1bmN0aW9uIHR1cm4oZG9vcjo6QWJzdHJhY3REb29yKQogIHR1cm4oZG9vci5rbm9iKQogIGRvb3IKZW5kCmZ1bmN0aW9uIHVudHVybihkb29yOjpBYnN0cmFjdERvb3IpCiAgdW50dXJuKGRvb3Iua25vYikKICBkb29yCmVuZApmdW5jdGlvbiBvcGVuZG9vcihkb29yOjpBYnN0cmFjdERvb3IpCiAgZG9vci5jbG9zZWQgPSBmYWxzZQogIGRvb3IKZW5kCmZ1bmN0aW9uIGNsb3NlZG9vcihkb29yOjpBYnN0cmFjdERvb3IpCiAgZG9vci5jbG9zZWQgPSB0cnVlCiAgZG9vcgplbmQKZnVuY3Rpb24gcHVsbChkb29yOjpBYnN0cmFjdERvb3IpCiAgaWYgY2xvc2VhYmxlKGRvb3IpCiAgICBjbG9zZWRvb3IoZG9vcikKICBlbmQKICBkb29yCmVuZApmdW5jdGlvbiBwdXNoKGRvb3I6OkFic3RyYWN0RG9vcikKICBpZiBvcGVuYWJsZShkb29yKQogICAgb3BlbmRvb3IoZG9vcikKICBlbmQKICBkb29yCmVuZAoKdHlwZSBEb29yV2l0aFN0b3BwZXIgJmx0OzogQWJzdHJhY3REb29yV2l0aFN0b3BwZXIKICBjbG9zZWQgOjogQm9vbAogIGtub2IgOjogS25vYgogIHN0b3BwZXJlZCA6OiBCb29sCmVuZAoKRG9vcldpdGhTdG9wcGVyKGNsb3NlZDo6Qm9vbCx1bnR1cm5lZDo6Qm9vbCxzdG9wcGVyZWQ6OkJvb2wpPURvb3JXaXRoU3RvcHBlcihjbG9zZWQsS25vYih1bnR1cm5lZCksc3RvcHBlcmVkKQoKY2xvc2VhYmxlKGRvb3I6OkFic3RyYWN0RG9vcldpdGhTdG9wcGVyKSA9ICFkb29yLnN0b3BwZXJlZApmdW5jdGlvbiBzZXRzdG9wcGVyKGRvb3I6OkFic3RyYWN0RG9vcldpdGhTdG9wcGVyKQogIGRvb3Iuc3RvcHBlcmVkID0gdHJ1ZQogIGRvb3IKZW5kCmZ1bmN0aW9uIHVuc2V0c3RvcHBlcihkb29yOjpBYnN0cmFjdERvb3JXaXRoU3RvcHBlcikKICBkb29yLnN0b3BwZXJlZCA9IGZhbHNlCiAgZG9vcgplbmQKZnVuY3Rpb24gcHVzaChkb29yOjpEb29yV2l0aFN0b3BwZXIpCiAgdW5zZXRzdG9wcGVyKGRvb3IpCiAgaWYgb3BlbmFibGUoZG9vcikKICAgICBvcGVuZG9vcihkb29yKQogIGVuZAogIGRvb3IKZW5kCgp0eXBlIERvb3JXaXRoQ2xvc2VyICZsdDs6IEFic3RyYWN0RG9vcldpdGhDbG9zZXIKICBjbG9zZWQgOjogQm9vbAogIGtub2IgOjogS25vYgogIGNsb3NlcmRlbGF5IDo6IEZsb2F0NjQKZW5kCkRvb3JXaXRoQ2xvc2VyKGNsb3NlZDo6Qm9vbCx1bnR1cm5lZDo6Qm9vbCxjbG9zZXJkZWxheTo6RmxvYXQ2NCk9RG9vcldpdGhDbG9zZXIoY2xvc2VkLEtub2IodW50dXJuZWQpLGNsb3NlcmRlbGF5KQpmdW5jdGlvbiBhdXRvY2xvc2UoZG9vcjo6QWJzdHJhY3REb29yV2l0aENsb3NlcikKICBzbGVlcChkb29yLmNsb3NlcmRlbGF5KQogIGRvb3IuY2xvc2VkID0gdHJ1ZQplbmQKZnVuY3Rpb24gb3BlbmRvb3IoZG9vcjo6QWJzdHJhY3REb29yV2l0aENsb3NlcikKICBkb29yLmNsb3NlZCA9IGZhbHNlCiAgc2NoZWR1bGUoQHRhc2sgYXV0b2Nsb3NlKGRvb3IpKQogIGRvb3IKZW5kCgoKdHlwZSBEb29yV2l0aFN0b3BwZXJBbmRDbG9zZXIgJmx0OzogQWJzdHJhY3REb29yV2l0aFN0b3BwZXIKICBjbG9zZWQgOjogQm9vbAogIGtub2IgOjogS25vYgogIHN0b3BwZXJlZCA6OiBCb29sCiAgY2xvc2VyZGVsYXkgOjogRmxvYXQ2NAplbmQKRG9vcldpdGhTdG9wcGVyQW5kQ2xvc2VyKGNsb3NlZDo6Qm9vbCx1bnR1cm5lZDo6Qm9vbCxzdG9wcGVyZWQ6OkJvb2wsY2xvc2VyZGVsYXk6OkZsb2F0NjQpPURvb3JXaXRoU3RvcHBlckFuZENsb3NlcihjbG9zZWQsS25vYih1bnR1cm5lZCksc3RvcHBlcmVkLGNsb3NlcmRlbGF5KQpmdW5jdGlvbiBhdXRvY2xvc2UoZG9vcjo6RG9vcldpdGhTdG9wcGVyQW5kQ2xvc2VyKQogIHNsZWVwKGRvb3IuY2xvc2VyZGVsYXkpCiAgcHVsbChkb29yKQplbmQKZnVuY3Rpb24gb3BlbmRvb3IoZG9vcjo6RG9vcldpdGhTdG9wcGVyQW5kQ2xvc2VyKQogIGRvb3IuY2xvc2VkID0gZmFsc2UKICBzY2hlZHVsZShAdGFzayBhdXRvY2xvc2UoZG9vcikpCiAgZG9vcgplbmQKZnVuY3Rpb24gdW5zZXRzdG9wcGVyKGRvb3I6OkRvb3JXaXRoU3RvcHBlckFuZENsb3NlcikKICBkb29yLnN0b3BwZXJlZCA9IGZhbHNlCiAgc2NoZWR1bGUoQHRhc2sgYXV0b2Nsb3NlKGRvb3IpKQogIGRvb3IKZW5kCgplbmQKCgphZGRwcm9jcygxKQoKdXNpbmcgRnVja2luU3R1cGlkRG9vcgpkb29yID0gRG9vcih0cnVlLHRydWUpCmRvb3IgfCZndDsgc3RhdGUKZG9vciB8Jmd0OyBwdXNoIHwmZ3Q7IHN0YXRlCmRvb3IgfCZndDsgdHVybiB8Jmd0OyBwdXNoIHwmZ3Q7IHN0YXRlCmRvb3IgfCZndDsgdW50dXJuIHwmZ3Q7IHB1bGwgfCZndDsgcHVzaCB8Jmd0OyBzdGF0ZQpkb29yIHwmZ3Q7IHR1cm4gfCZndDsgcHVzaCB8Jmd0OyBzdGF0ZQpkb29yID0gRG9vcldpdGhTdG9wcGVyKHRydWUsdHJ1ZSx0cnVlKQpkb29yIHwmZ3Q7IHB1c2ggfCZndDsgc3RhdGUKZG9vciB8Jmd0OyB0dXJuIHwmZ3Q7IHB1c2ggfCZndDsgc3RhdGUKZG9vciB8Jmd0OyBzZXRzdG9wcGVyIHwmZ3Q7IHB1bGwgfCZndDsgc3RhdGUKZG9vciB8Jmd0OyBwdXNoIHwmZ3Q7IHB1bGwgfCZndDsgc3RhdGUKZG9vciB8Jmd0OyBwdXNoIHwmZ3Q7IHN0YXRlCmRvb3IgPSBEb29yV2l0aENsb3Nlcih0cnVlLHRydWUsMC41KQpkb29yIHwmZ3Q7IHR1cm4gfCZndDsgcHVzaCB8Jmd0OyBzdGF0ZQpkb29yIHwmZ3Q7IHN0YXRlCmRvb3IgfCZndDsgdW50dXJuIHwmZ3Q7IHB1c2ggfCZndDsgc3RhdGUKZG9vciA9IERvb3JXaXRoU3RvcHBlckFuZENsb3Nlcih0cnVlLHRydWUsdHJ1ZSwwLjUpCmRvb3IgfCZndDsgdHVybiB8Jmd0OyBwdXNoIHwmZ3Q7IHN0YXRlCmRvb3IgfCZndDsgc3RhdGUKZG9vciB8Jmd0OyB0dXJuIHwmZ3Q7IHB1c2ggfCZndDsgc2V0c3RvcHBlciB8Jmd0OyBzdGF0ZQpkb29yIHwmZ3Q7IHN0YXRlCmRvb3IgfCZndDsgdW5zZXRzdG9wcGVyIHwmZ3Q7IHN0YXRlCmRvb3IgfCZndDsgc3RhdGUKCg==
module FuckinStupidDoor
export Door,DoorWithCloser,DoorWithStopper,DoorWithStopperAndCloser,state,push,pull,setstopper,unsetstopper,turn,unturn
abstract AbstractDoor
abstract AbstractDoorWithStopper <: AbstractDoor
abstract AbstractDoorWithCloser <: AbstractDoor
openable(door::AbstractDoor)=!door.knob.unturned
closeable(door::AbstractDoor)=true
state(door::AbstractDoor)=ifelse(door.closed,"closed","opened")
type Knob
unturned :: Bool
end
function turn(knob::Knob)
knob.unturned=false
knob
end
function unturn(knob::Knob)
knob.unturned=true
knob
end
type Door <:AbstractDoor
closed :: Bool
knob :: Knob
end
Door(closed::Bool,latched::Bool)=Door(closed,Knob(latched))
function turn(door::AbstractDoor)
turn(door.knob)
door
end
function unturn(door::AbstractDoor)
unturn(door.knob)
door
end
function opendoor(door::AbstractDoor)
door.closed = false
door
end
function closedoor(door::AbstractDoor)
door.closed = true
door
end
function pull(door::AbstractDoor)
if closeable(door)
closedoor(door)
end
door
end
function push(door::AbstractDoor)
if openable(door)
opendoor(door)
end
door
end
type DoorWithStopper <: AbstractDoorWithStopper
closed :: Bool
knob :: Knob
stoppered :: Bool
end
DoorWithStopper(closed::Bool,unturned::Bool,stoppered::Bool)=DoorWithStopper(closed,Knob(unturned),stoppered)
closeable(door::AbstractDoorWithStopper) = !door.stoppered
function setstopper(door::AbstractDoorWithStopper)
door.stoppered = true
door
end
function unsetstopper(door::AbstractDoorWithStopper)
door.stoppered = false
door
end
function push(door::DoorWithStopper)
unsetstopper(door)
if openable(door)
opendoor(door)
end
door
end
type DoorWithCloser <: AbstractDoorWithCloser
closed :: Bool
knob :: Knob
closerdelay :: Float64
end
DoorWithCloser(closed::Bool,unturned::Bool,closerdelay::Float64)=DoorWithCloser(closed,Knob(unturned),closerdelay)
function autoclose(door::AbstractDoorWithCloser)
sleep(door.closerdelay)
door.closed = true
end
function opendoor(door::AbstractDoorWithCloser)
door.closed = false
schedule(@task autoclose(door))
door
end
type DoorWithStopperAndCloser <: AbstractDoorWithStopper
closed :: Bool
knob :: Knob
stoppered :: Bool
closerdelay :: Float64
end
DoorWithStopperAndCloser(closed::Bool,unturned::Bool,stoppered::Bool,closerdelay::Float64)=DoorWithStopperAndCloser(closed,Knob(unturned),stoppered,closerdelay)
function autoclose(door::DoorWithStopperAndCloser)
sleep(door.closerdelay)
pull(door)
end
function opendoor(door::DoorWithStopperAndCloser)
door.closed = false
schedule(@task autoclose(door))
door
end
function unsetstopper(door::DoorWithStopperAndCloser)
door.stoppered = false
schedule(@task autoclose(door))
door
end
end
addprocs(1)
using FuckinStupidDoor
door = Door(true,true)
door |> state
door |> push |> state
door |> turn |> push |> state
door |> unturn |> pull |> push |> state
door |> turn |> push |> state
door = DoorWithStopper(true,true,true)
door |> push |> state
door |> turn |> push |> state
door |> setstopper |> pull |> state
door |> push |> pull |> state
door |> push |> state
door = DoorWithCloser(true,true,0.5)
door |> turn |> push |> state
door |> state
door |> unturn |> push |> state
door = DoorWithStopperAndCloser(true,true,true,0.5)
door |> turn |> push |> state
door |> state
door |> turn |> push |> setstopper |> state
door |> state
door |> unsetstopper |> state
door |> state