Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Ported events, now Tasks

  • Loading branch information...
commit 0bab76bd4f0dd207e921028f95f6073a1e484728 1 parent 767b998
@zkat authored
View
98 src/event.lisp
@@ -1,98 +0,0 @@
-;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; indent-tabs-mode: nil -*-
-
-;;;; This file is part of Until It Dies
-
-;;;; event.lisp
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(in-package :until-it-dies)
-
-;;;
-;;; Event prototype
-;;;
-(defproto =event= ()
- ((payload (lambda () (print "=event='s event fired.")))
- (exec-time 0))
- :documentation
- "An event is a block of code that is executed by an event-queue.
-Event firing can be delayed by milliseconds, and they are guaranteed
-to not fire until they are 'cooked'.
-Events can be asynchronously added to an event-queue, which can
-remain inactive until execution is ready to start again, and they
-will still be 'fired' in the order they were added.")
-
-(defvar *event-queue*)
-(defun make-event (payload &key
- (queue *event-queue*)
- (delay 0)
- (event-prototype =event=))
- "Generates one or more events that execute PAYLOAD."
- (push-event (defobject (event-prototype)
- ((payload payload)
- (exec-frame (+ delay (now)))))
- queue))
-
-;; TODO: FORK was simplified. I may need to add looping to it again. Keep it like this for now.
-(defmacro fork ((&key queue delay) &body body)
- "Turns BODY into a function to be added as a payload to an =event= object, which
- will be delayed by DELAY milliseconds, and added to QUEUE."
- `(make-event (lambda () ,@body)
- ,@(when queue `(:queue ,queue))
- ,@(when delay `(:delay ,delay))))
-
-(defmacro with-event-queue (queue &body body)
- `(let ((*event-queue* ,queue))
- ,@body))
-
-(defreply execute-event ((event =event=))
- "Executes a standard event. Nothing fancy, just a funcall."
- (funcall (payload event)))
-
-(defreply cookedp ((event =event=))
- "Simply checks that it doesn't shoot its load prematurely."
- (let ((time-difference (- (exec-time event) (now))))
- (when (<= time-difference 0)
- t)))
-
-;;;
-;;; Event-queue
-;;;
-(defproto =event-queue= ()
- ((queue (make-priority-queue :key #'exec-time)))
- :documentation "An event queue is a container for events. Events are inserted
-into it and automatically sorted according to the event's execution time. The queue
-works like a min-priority queue. The top event can be peeked at, or popped.")
-
-(defreply init-object :after ((obj =event-queue=) &key)
- (setf (queue obj) (make-priority-queue :key #'exec-time)))
-
-;;; - Most of these replies wrap around the priority queue API in util/priority-queue.lisp
-;;; It is pretty much a standard by-the-book min-priority-queue, with items sorted by
-;;; #'exec-time.
-(defreply push-event ((event =event=) (queue =event-queue=))
- (priority-queue-insert (queue queue) event)
- t)
-
-(defreply peek-next-event ((queue =event-queue=))
- (priority-queue-minimum (queue queue)))
-
-(defreply pop-next-event ((queue =event-queue=))
- (priority-queue-extract-minimum (queue queue)))
-
-(defreply event-available-p ((queue =event-queue=))
- "Simply peeks to see if there's an event in the queue, and if it's cooked."
- (when (and (peek-next-event queue)
- (cookedp (peek-next-event queue)))
- t))
-
-(defreply clear-events ((queue =event-queue=))
- (setf (queue queue) (make-priority-queue :key #'exec-time)))
-
-(defreply process-next-event ((queue =event-queue=))
- (when (event-available-p queue)
- (execute-event (pop-next-event queue))))
-
-(defreply process-cooked-events ((queue =event-queue=))
- (loop
- while (event-available-p queue)
- do (process-next-event queue)))
View
16 src/packages.lisp
@@ -25,6 +25,22 @@
:detach
:detach-all
+ ;; Tasks
+ :task
+ :fork
+ :with-task-queue
+ :*task-queue*
+ :execute-task
+ :cookedp
+ :task-queue
+ :push-task
+ :peek-next-task
+ :pop-next-task
+ :task-available-p
+ :clear-tasks
+ :process-next-task
+ :process-cooked-tasks
+
;; events
:on-update
:on-draw
View
103 src/task.lisp
@@ -0,0 +1,103 @@
+;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; indent-tabs-mode: nil -*-
+
+;;;; This file is part of Until It Dies
+
+;;;; task.lisp
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(in-package :until-it-dies)
+
+;;;
+;;; Tasks
+;;;
+(defclass task ()
+ ((payload :accessor payload :initarg :payload
+ :initform (error "Task must be given a payload function."))
+ (exec-time :accessor exec-time))
+ (:documentation
+ "An task is a block of code that is executed by an task-queue.
+Task firing can be delayed by milliseconds, and they are guaranteed
+to not fire until they are 'cooked'.
+Tasks can be asynchronously added to an task-queue, which can
+remain inactive until execution is ready to start again, and they
+will still be 'fired' in the order they were added." ))
+
+(defvar *task-queue*)
+(defmethod initialize-instance :after ((task task) &key
+ (queue *task-queue*)
+ (delay 0))
+ (setf (exec-time task) (+ delay (now)))
+ (push-task task queue))
+
+;; TODO: FORK was simplified. I may need to add looping to it again. Keep it like this for now.
+(defmacro fork ((&key queue delay (task-class 'task)) &body body)
+ "Turns BODY into a function to be added as a payload to an =task= object, which
+ will be delayed by DELAY milliseconds, and added to QUEUE."
+ `(make-instance ,task-class
+ :payload (lambda () ,@body)
+ ,@(when queue `(:queue ,queue))
+ ,@(when delay `(:delay ,delay))))
+
+(defmacro with-task-queue (queue &body body)
+ `(let ((*task-queue* ,queue))
+ ,@body))
+
+(defgeneric execute-task (task)
+ (:documentation "Executes a standard task. Nothing fancy, just a funcall.")
+ (:method ((task task))
+ (funcall (payload task))))
+
+(defgeneric cookedp (task)
+ (:documentation "Simply checks that it doesn't shoot its load prematurely.")
+ (:method ((task task))
+ (let ((time-difference (- (exec-time task) (now))))
+ (when (<= time-difference 0)
+ t))))
+
+;;;
+;;; Task-queue
+;;;
+(defclass task-queue ()
+ ((queue :initform (make-priority-queue :key #'exec-time) :accessor queue))
+ (:documentation
+ "An task queue is a container for tasks. Tasks are inserted
+into it and automatically sorted according to the task's execution time. The queue
+works like a min-priority queue. The top task can be peeked at, or popped."))
+
+;;; - Most of these functions wrap around the priority queue API in util/priority-queue.lisp
+;;; It is pretty much a standard by-the-book min-priority-queue, with items sorted by
+;;; #'exec-time.
+(defgeneric push-task (task queue)
+ (:method ((task task) (queue task-queue))
+ (priority-queue-insert (queue queue) task)
+ t))
+
+(defgeneric peek-next-task (queue)
+ (:method ((queue task-queue))
+ (priority-queue-minimum (queue queue))))
+
+(defgeneric pop-next-task (queue)
+ (:method ((queue task-queue))
+ (priority-queue-extract-minimum (queue queue))))
+
+(defgeneric task-available-p (queue)
+ (:documentation "Simply peeks to see if there's an task in the queue, and if it's cooked.")
+ (:method ((queue task-queue))
+ (when (and (peek-next-task queue)
+ (cookedp (peek-next-task queue)))
+ t)))
+
+(defgeneric clear-tasks (queue)
+ (:method ((queue task-queue))
+ (setf (queue queue) (make-priority-queue :key #'exec-time))))
+
+(defgeneric process-next-task (queue)
+ (:method ((queue task-queue))
+ (when (task-available-p queue)
+ (execute-task (pop-next-task queue)))))
+
+(defgeneric process-cooked-tasks (queue)
+ (:method ((queue task-queue))
+ (loop
+ while (task-available-p queue)
+ do (process-next-task queue))))
View
1  until-it-dies.base.asd
@@ -22,6 +22,7 @@
(:file "split-sequence")
(:file "utils")))
(:file "base-api":depends-on ("util"))
+ (:file "task" :depends-on ("util"))
(:file "clock" :depends-on ("util" "base-api"))
(:file "colors" :depends-on ("util" "base-api"))
(:file "primitives" :depends-on ("colors" "base-api"))
Please sign in to comment.
Something went wrong with that request. Please try again.