Skip to content

Instantly share code, notes, and snippets.

@Ravenstine
Created September 8, 2015 05:29
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ravenstine/f84f789caf44a941c916 to your computer and use it in GitHub Desktop.
Save Ravenstine/f84f789caf44a941c916 to your computer and use it in GitHub Desktop.
A very simple event loop written in Crystal. (crystal-lang.org)
module Reactor
class Task
property :block
def initialize(timestamp=Time.now, milliseconds=0, &block : Loop ->)
@block = block
@timestamp = timestamp.epoch_ms
@milliseconds = milliseconds
end
def run reactor
@block.call reactor
end
end
class Timeout < Task
def run *args
if Time.now.epoch_ms >= (@timestamp + @milliseconds)
super
else
args[0].add_to_stack self
end
end
end
class PeriodicTimer < Task
def run *args
if Time.now.epoch_ms >= (@timestamp + @milliseconds)
super
@timestamp = Time.now.epoch_ms
end
args[0].add_to_stack self
end
end
class Loop
property :stack
def initialize(&block : Loop ->)
@stack = Array(Task|Timeout).new
@stopped = false
next_tick &block
react
end
def next_tick(&block : Loop ->)
@stack << Task.new(Time.now, 0, &block)
end
def set_timeout(milliseconds, &block : Loop ->)
@stack << Timeout.new(Time.now, milliseconds, &block)
end
def stop
@stopped = true
end
def add_to_stack obj
@stack << obj
end
def set_interval(milliseconds, &block: Loop ->)
@stack << PeriodicTimer.new(Time.now, milliseconds, &block)
end
private def react
loop do
unless @stopped
some_process = @stack.pop if @stack.length > 0
some_process.run(self) if some_process
else
break
end
end
end
end
end
Reactor::Loop.new do |reactor|
puts "I like eggs"
reactor.set_timeout 3000 do
puts "I like flowers"
reactor.set_interval 5000 do
puts ["foo", "bar", "baz"].sample
end
end
puts "I like trees"
end
@fernandes
Copy link

@Ravenstine just forked and updated to work with crystal 0.16.0

https://gist.github.com/fernandes/c3da8b8a472b8c7f0b6c2eb86e735607

@Ravenstine
Copy link
Author

Sweet, @fernandes!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment