-(define current-engine-mutex (make-mutex))
-(define current-engine-list '())
-
-(define (current-engine)
- (with-mutex current-engine-mutex
- (assoc-ref current-engine-list (current-thread))))
-
-(define (set-current-engine! engine)
- (with-mutex current-engine-mutex
- (set! current-engine-list
- (cond (engine
- (assoc-set! current-engine-list (current-thread) engine))
- (else
- (assoc-remove! current-engine-list (current-thread)))))))
-
-(define* (get-entity key #:key (engine (current-engine)))
- (assoc key (car (engine-entities engine))))
-
-(define-syntax define-entity-setter
- (syntax-rules ()
- ((_ name! name)
- (define (name! . args)
- (let ((f (apply name args))
- (engine (current-engine)))
- (receive (e c r) (f (car (engine-entities engine)) (cadr (engine-entities engine)))
- (set-engine-entities! engine (list e c))
- r))))))
-
-(define-entity-setter new-entity! new-entity)
-(define-entity-setter remove-entity! remove-entity)
-(define-entity-setter set-entity! set-entity)
-(define-entity-setter set-entity-components! set-entity-components)
-(define-entity-setter remove-entity-components! remove-entity-components)
+(export make-engine
+ define-engine
+ engine-running?)
+
+
+;;; Engine execution
+
+(define* (start-engine engine #:optional (socket #f))
+ (catch
+ #t
+ (lambda ()
+ (with-mutex (engine-running-mutex engine)
+ (let loop ((coop-server (if socket (spawn-coop-repl-server socket) #f)))
+ (let ((t (current-utime))
+ (delay 0)
+ (halt #f))
+ (for-each
+ (lambda (s) (eval-system s engine))
+ (engine-systems engine))
+ (set! delay (- (inexact->exact (* (engine-property engine 'step) 1000000))
+ (- (current-utime) t)))
+ (set! halt (engine-stopping? engine #:clean #t))
+ (if coop-server
+ (poll-coop-repl-server coop-server))
+ (cond ((not halt)
+ (cond ((> delay 0)
+ (usleep delay)))
+ (loop coop-server))
+ (else
+ (if coop-server
+ (stop-server-and-clients!))))))))
+ (lambda (key args)
+ #f)))
+
+(define (eval-system system engine)
+ (call-with-values
+ (lambda () (system (engine-entities engine)))
+ (lambda vals
+ (let ((changes (car vals)))
+ (cond ((entities-changes? changes)
+ (set-engine-entities! engine
+ (modify-entities (engine-entities engine)
+ (get-entities-changes changes))))))
+ (apply values vals))))