mirror of
https://github.com/logos-storage/swarmsim.git
synced 2026-01-02 13:53:07 +00:00
add basic event-driven engine and scaffolding
This commit is contained in:
commit
f70988020b
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
*
|
||||||
|
!*/
|
||||||
|
!*.*
|
||||||
|
nimbledeps
|
||||||
|
nimble.develop
|
||||||
|
nimble.paths
|
||||||
5
LICENSE.md
Normal file
5
LICENSE.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Licensed and distributed under either of
|
||||||
|
[MIT license](http://opensource.org/licenses/MIT) or
|
||||||
|
[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
at your option. These files may not be copied, modified, or distributed except
|
||||||
|
according to those terms.
|
||||||
4
README.md
Normal file
4
README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
swarmsim
|
||||||
|
========
|
||||||
|
|
||||||
|
A simulator for experimenting with swarm protocols. There is not much to see yet. :-)
|
||||||
1
config.nims
Normal file
1
config.nims
Normal file
@ -0,0 +1 @@
|
|||||||
|
switch("path", "$projectDir/src")
|
||||||
5
swarmsim.nim
Normal file
5
swarmsim.nim
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# This is just an example to get you started. A typical binary package
|
||||||
|
# uses this file as the main entry point of the application.
|
||||||
|
|
||||||
|
import ./swarmsim/schedulable
|
||||||
|
import ./swarmsim/eventdrivenengine
|
||||||
19
swarmsim.nimble
Normal file
19
swarmsim.nimble
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Package
|
||||||
|
|
||||||
|
version = "0.1.0"
|
||||||
|
author = "gmega"
|
||||||
|
description = "Simple swarm simulator"
|
||||||
|
license = "MIT"
|
||||||
|
srcDir = "src"
|
||||||
|
installExt = @["nim"]
|
||||||
|
bin = @["swarm_sim"]
|
||||||
|
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
|
requires "nim >= 2.0.0"
|
||||||
|
|
||||||
|
|
||||||
|
# Tasks
|
||||||
|
task test, "Run unit tests":
|
||||||
|
exec "nim c -r tests/all_tests.nim"
|
||||||
31
swarmsim/eventdrivenengine.nim
Normal file
31
swarmsim/eventdrivenengine.nim
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import std/options
|
||||||
|
|
||||||
|
import pkg/swarmsim/types
|
||||||
|
import pkg/swarmsim/schedulable
|
||||||
|
|
||||||
|
proc current_time*(self: EventDrivenEngine): uint64 {.inline.} = self.current_time
|
||||||
|
|
||||||
|
proc schedule*(self: EventDrivenEngine, schedulable: Schedulable): EventDrivenEngine =
|
||||||
|
self.queue.push(schedulable)
|
||||||
|
self
|
||||||
|
|
||||||
|
proc scheduleAll*[T: Schedulable](self: EventDrivenEngine, schedulables: seq[T]): void =
|
||||||
|
for schedulable in schedulables:
|
||||||
|
discard self.schedule(schedulable)
|
||||||
|
|
||||||
|
proc nextStep*(self: EventDrivenEngine): Option[Schedulable] =
|
||||||
|
if len(self.queue) == 0:
|
||||||
|
return none(Schedulable)
|
||||||
|
|
||||||
|
let schedulable = self.queue.pop()
|
||||||
|
self.current_time = schedulable.time
|
||||||
|
schedulable.scheduled(engine = self)
|
||||||
|
|
||||||
|
some(schedulable)
|
||||||
|
|
||||||
|
proc run*(self: EventDrivenEngine): void =
|
||||||
|
while self.nextStep().isSome:
|
||||||
|
discard
|
||||||
|
|
||||||
|
export EventDrivenEngine
|
||||||
|
export options
|
||||||
9
swarmsim/schedulable.nim
Normal file
9
swarmsim/schedulable.nim
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import pkg/swarmsim/types
|
||||||
|
|
||||||
|
func `<`*(self: Schedulable, other: Schedulable): bool =
|
||||||
|
return self.time < other.time
|
||||||
|
|
||||||
|
method scheduled*(self: Schedulable, engine: EventDrivenEngine): void {.base.} =
|
||||||
|
quit "unimplemented"
|
||||||
|
|
||||||
|
export Schedulable
|
||||||
14
swarmsim/types.nim
Normal file
14
swarmsim/types.nim
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import std/heapqueue
|
||||||
|
|
||||||
|
type
|
||||||
|
Schedulable* = ref object of RootObj
|
||||||
|
## A `Schedulable` is something that can be scheduled for execution in an
|
||||||
|
## `EventDrivenEngine`.
|
||||||
|
time*: uint64
|
||||||
|
|
||||||
|
type
|
||||||
|
EventDrivenEngine* = ref object of RootObj
|
||||||
|
current_time*: uint64
|
||||||
|
queue*: HeapQueue[Schedulable]
|
||||||
|
|
||||||
|
export heapqueue
|
||||||
1
tests/all_tests.nim
Normal file
1
tests/all_tests.nim
Normal file
@ -0,0 +1 @@
|
|||||||
|
import ./swarmsim/eventdrivenengine
|
||||||
1
tests/nim.cfg
Normal file
1
tests/nim.cfg
Normal file
@ -0,0 +1 @@
|
|||||||
|
--path:".."
|
||||||
39
tests/swarmsim/eventdrivenengine.nim
Normal file
39
tests/swarmsim/eventdrivenengine.nim
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import unittest
|
||||||
|
import sequtils
|
||||||
|
import sugar
|
||||||
|
|
||||||
|
import std/algorithm
|
||||||
|
|
||||||
|
import pkg/swarmsim/schedulable
|
||||||
|
import pkg/swarmsim/eventdrivenengine
|
||||||
|
|
||||||
|
type
|
||||||
|
TimedSchedulable = ref object of Schedulable
|
||||||
|
scheduledAt: uint64
|
||||||
|
|
||||||
|
method scheduled(schedulable: TimedSchedulable, engine: EventDrivenEngine) =
|
||||||
|
schedulable.scheduledAt = engine.current_time
|
||||||
|
|
||||||
|
suite "event driven engine tests":
|
||||||
|
|
||||||
|
test "should run schedulables at the right time":
|
||||||
|
|
||||||
|
let times = @[1, 10, 5].map(time => uint64(time))
|
||||||
|
let schedulables = times.map(time => TimedSchedulable(time: time))
|
||||||
|
|
||||||
|
let engine = EventDrivenEngine()
|
||||||
|
|
||||||
|
engine.scheduleAll(schedulables)
|
||||||
|
|
||||||
|
for time in times.sorted:
|
||||||
|
let result = engine.nextStep().get()
|
||||||
|
check(result.time == time)
|
||||||
|
|
||||||
|
check(engine.nextStep().isNone)
|
||||||
|
|
||||||
|
for schedulable in schedulables:
|
||||||
|
check(schedulable.scheduledAt == schedulable.time)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user