From 78cc7b19255878a5bd8a29a3af36d3b215bce08d Mon Sep 17 00:00:00 2001 From: Javier Sancho Date: Fri, 12 Jul 2013 15:42:58 +0200 Subject: [PATCH] Making systems; systems return a lambda function for process modifications at entities and components * src/system.scm: export-component new-entity * src/test.scm: system functions testing --- src/system.scm | 68 ++++++++++++++++++++++++++++++++++++++++++++------ src/test.scm | 39 +++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 src/test.scm diff --git a/src/system.scm b/src/system.scm index 4da0b1c..6f9f8cb 100644 --- a/src/system.scm +++ b/src/system.scm @@ -22,7 +22,7 @@ ;;; Component definitions -(define (make-symbol . args) +(define (symbol-concatenate . args) (string->symbol (string-concatenate (map (lambda (a) (if (symbol? a) (symbol->string a) a)) args)))) @@ -31,23 +31,62 @@ `(begin (use-modules (srfi srfi-9) (srfi srfi-9 gnu)) (define-record-type ,name - (,(make-symbol "make-" name) ,@args) - ,(make-symbol name "?") - ,@(map (lambda (a) (list a (make-symbol name "-" a) (make-symbol "set-" name "-" a "!"))) args)) + (,(symbol-concatenate "make-" name) ,@args) + ,(symbol-concatenate name "?") + ,@(map (lambda (a) (list a (symbol-concatenate name "-" a) (symbol-concatenate "set-" name "-" a "!"))) args)) (set-record-type-printer! ,name (lambda (record port) (format port "#<[~a]" ',name) - ,@(map (lambda (a) `(format port " ~a: ~a" ',a (,(make-symbol name "-" a) record))) args) + ,@(map (lambda (a) `(format port " ~a: ~a" ',a (,(symbol-concatenate name "-" a) record))) args) (format port ">"))) ',name)) +(define (export-component component) + (let ((name (record-type-name component)) + (m (current-module))) + (module-export! m (list + (symbol-concatenate "make-" name) + (symbol-concatenate name "?"))) + (for-each + (lambda (a) + (module-export! (current-module) + (list + (symbol-concatenate name "-" a) + (symbol-concatenate "set-" name "-" a "!")))) + (record-type-fields component)))) + (define (get-component-type component) (record-type-name (record-type-descriptor component))) (export define-component + export-component get-component-type) +;;; Entities and components + +(define (new-entity new-components entities components) + (let ((key (gensym))) + (values + (acons key (map (lambda (c) `(,(get-component-type c) . ,c)) new-components) entities) + (register-components key new-components components) + key))) + +(define* (register-components entity components clist) + (cond ((null? components) clist) + (else + (let* ((type (get-component-type (car components))) + (elist (assoc-ref clist type))) + (register-components entity (cdr components) + (assoc-set! clist type + (cond (elist + (lset-adjoin eq? elist entity)) + (else + (list entity))))))))) + +(export new-entity) + + ;;; Making systems (define* (find-entities-by-components c t) @@ -64,9 +103,24 @@ (lambda (entities components) (let* ((e (find-entities-by-components components component-types)) (e* (map (lambda (x) (assoc x entities)) e)) - (e** (map (lambda (x) (cons (car x) (filter (lambda (x) (memq (get-component-type x) component-types)) (cdr x)))) e*))) - e**))) + (e** (map (lambda (x) (cons (car x) (filter (lambda (x) (memq (get-component-type x) component-types)) (cdr x)))) e*)) + (res (system-fun e**))) + (lambda* (#:optional (entities2 #f) (components2 #f)) + (let* ((e2 (if (and entities2 components2) + (find-entities-by-components components2 component-types) + e)) + (e2* (if (and entities2 components2) + (map (lambda (x) (assoc x entities2)) e2) + e*)) + (e2** (if (and entities2 components2) + (map (lambda (x) (cons (car x) (filter (lambda (x) (memq (get-component-type x) component-types)) (cdr x)))) e2*) + e**))) + e2**))))) +; ((1 a b) (2 a b c) (3 c)) +; ((1 a b) (2 a b)) +; ((1 a) (a b)) +; ((1 a) (3 c) (4 a b)) (export find-entities-by-components make-system) diff --git a/src/test.scm b/src/test.scm new file mode 100644 index 0000000..ebd17e9 --- /dev/null +++ b/src/test.scm @@ -0,0 +1,39 @@ +;;; Gacela, a GNU Guile extension for fast games development +;;; Copyright (C) 2013 by Javier Sancho Fernandez +;;; +;;; This program 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. +;;; +;;; This program 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 this program. If not, see . + + +(define-module (gacela test) + #:use-module (gacela system) + #:use-module (ice-9 receive)) + + +(define-component a x y) +(define-component b) +(define-component c) + +(export-component a) + +(define (test1) + (let ((entities '()) + (components '())) + (receive (e c n) (new-entity `(,(make-a 1 2) ,(make-b)) entities components) + (set! entities e) + (set! components c) + (display n) (newline)) + (display entities) (newline) + (display components) (newline))) + +(export test1) -- 2.39.2