composite-slot.scm 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. ;;; installed-scm-file
  2. ;;;; Copyright (C) 1999, 2000, 2001, 2006, 2015 Free Software Foundation, Inc.
  3. ;;;; Copyright (C) 1993-1998 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
  4. ;;;;
  5. ;;;; This library is free software; you can redistribute it and/or
  6. ;;;; modify it under the terms of the GNU Lesser General Public
  7. ;;;; License as published by the Free Software Foundation; either
  8. ;;;; version 3 of the License, or (at your option) any later version.
  9. ;;;;
  10. ;;;; This library is distributed in the hope that it will be useful,
  11. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. ;;;; Lesser General Public License for more details.
  14. ;;;;
  15. ;;;; You should have received a copy of the GNU Lesser General Public
  16. ;;;; License along with this library; if not, write to the Free Software
  17. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. ;;;;
  19. ;;;;
  20. ;;;; This file was based upon composite-slot.stklos from the STk distribution
  21. ;;;; version 4.0.1 by Erick Gallesio <eg@unice.fr>.
  22. ;;;;
  23. (define-module (oop goops composite-slot)
  24. :use-module (oop goops)
  25. :export (<composite-class>))
  26. ;;;
  27. ;;; (define-class CLASS SUPERS
  28. ;;; ...
  29. ;;; (OBJECT ...)
  30. ;;; ...
  31. ;;; (SLOT #:allocation #:propagated
  32. ;;; #:propagate-to '(PROPAGATION ...))
  33. ;;; ...
  34. ;;; #:metaclass <composite-class>)
  35. ;;;
  36. ;;; PROPAGATION ::= OBJECT | (OBJECT TARGETSLOT)
  37. ;;;
  38. ;;; The slot SLOT will be propagated to the slot TARGETSLOT in the object
  39. ;;; stored in slot OBJECT. If TARGETSLOT is omitted, assume that the target
  40. ;;; slot is named SLOT.
  41. ;;;
  42. (define-class <composite-class> (<class>))
  43. (define-method (compute-get-n-set (class <composite-class>) slot)
  44. (if (eq? (slot-definition-allocation slot) #:propagated)
  45. (compute-propagated-get-n-set slot)
  46. (next-method)))
  47. (define (compute-propagated-get-n-set s)
  48. (let ((prop (get-keyword #:propagate-to
  49. (slot-definition-options s)
  50. #f))
  51. (s-name (slot-definition-name s)))
  52. (if (not prop)
  53. (goops-error "Propagation not specified for slot ~S" s-name))
  54. (if (not (pair? prop))
  55. (goops-error "Bad propagation list for slot ~S" s-name))
  56. (let ((objects (map (lambda (p) (if (pair? p) (car p) p)) prop))
  57. (slots (map (lambda (p) (if (pair? p) (cadr p) s-name)) prop)))
  58. (let ((first-object (car objects))
  59. (first-slot (car slots)))
  60. (list
  61. ;; The getter
  62. (lambda (o)
  63. (slot-ref (slot-ref o first-object) first-slot))
  64. ;; The setter
  65. (if (null? (cdr objects))
  66. (lambda (o v)
  67. (slot-set! (slot-ref o first-object) first-slot v))
  68. (lambda (o v)
  69. (for-each (lambda (object slot)
  70. (slot-set! (slot-ref o object) slot v))
  71. objects
  72. slots))))))))