;;; Mudsync --- Live hackable MUD ;;; Copyright © 2016 Christopher Allan Webber ;;; ;;; This file is part of Mudsync. ;;; ;;; Mudsync is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or ;;; (at your option) any later version. ;;; ;;; Mudsync is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with Mudsync. If not, see . (define-module (mudsync run-game) #:use-module (mudsync game-master) #:use-module (8sync agenda) #:use-module (8sync repl) #:use-module (8sync systems actors) #:use-module (8sync systems actors debug) #:use-module (srfi srfi-1) #:use-module (ice-9 receive) #:use-module (ice-9 q) #:export (run-demo inject-special! make-special-injector ;; Debug stuff, might go away %live-gm %live-hive inject!)) ;;; Debugging stuff ;;; =============== ;; @@: Could these be parameterized and this still work? (define %live-gm #f) (define %live-hive #f) ;; Evil! This uses a global variable... but it's hard to give any more ;; convenient way of providing something for live hacking (which is ;; "quasi-evil for productivity's sake" anyway). You can set up your own ;; solution which doesn't use a global though. (define (inject! game-spec special-symbol) (display "Game hasn't been started...\n")) ;;; Game running stuff ;;; ================== (define* (run-demo game-spec default-room #:key repl-server) (define hive (make-hive)) (define new-conn-handler (make-default-room-conn-handler default-room)) (define gm (hive-create-actor-gimmie* hive "gm" #:new-conn-handler new-conn-handler)) (define initial-tasks (list (bootstrap-message hive (actor-id gm) 'init-world #:game-spec game-spec))) (define agenda (make-agenda #:pre-unwind-handler print-error-and-continue #:queue (list->q initial-tasks))) (set! %live-gm gm) (set! %live-hive hive) (receive (post-run-hook gameobj-injector) (make-special-injector agenda hive (actor-id gm)) ;; Set up injector for live hacking (set! inject! gameobj-injector) ;; Set up REPL sever (cond ;; If repl-server is an integer, we'll use that as the port ((integer? repl-server) (spawn-and-queue-repl-server! agenda repl-server)) (repl-server (spawn-and-queue-repl-server! agenda))) (start-agenda agenda #:post-run-hook post-run-hook))) (define (inject-special! queue hive gm-id game-spec special-symbol) (define gameobj-spec (or (find (lambda (entry) (eq? (car entry) special-symbol)) game-spec) (throw 'no-such-symbol "Can't find such a symbol in the game-spec" #:symbol special-symbol))) (define task (bootstrap-message hive gm-id 'inject-special! #:special-symbol special-symbol #:gameobj-spec gameobj-spec)) (enq! queue task) 'done) (define (queue-injected-tasks-on-agenda! agenda inject-queue) "Inject tasks from the inject-queue onto the agenda queue." (while (not (q-empty? inject-queue)) (enq! (agenda-queue agenda) (q-pop! inject-queue)))) (define* (make-special-injector agenda hive gm-id) "Make a post-run-hook and gameobj injector for quick live hacking." (define inject-queue (make-q)) (values (lambda (agenda) (queue-injected-tasks-on-agenda! agenda inject-queue)) (lambda (game-spec special-symbol) (inject-special! inject-queue hive gm-id game-spec special-symbol))))