Guest User

Untitled

a guest
Jan 21st, 2019
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.90 KB | None | 0 0
  1. (in-package :first-light.prefab)
  2.  
  3. (defclass node ()
  4. ((%name :reader name
  5. :initarg :name)
  6. (%prefab :reader prefab
  7. :initarg :prefab)
  8. (%data :reader data
  9. :initarg :data)
  10. (%path :reader path
  11. :initarg :path)
  12. (%components :reader components
  13. :initform (fl.util:dict #'eq))
  14. (%parent :reader parent
  15. :initarg :parent
  16. :initform nil)
  17. (%children :reader children
  18. :initform (fl.util:dict #'equal))
  19. (%merge-policy :reader merge-policy
  20. :initarg :merge-policy)))
  21.  
  22. (fl.util:define-printer (node stream :type t)
  23. (format stream "~a" (path node)))
  24.  
  25. (defun make-node-path (parent name)
  26. (concatenate 'string (when parent (path parent)) "/" name))
  27.  
  28. (defun make-node (name data &key prefab parent merge-policy)
  29. (let* ((prefab (or prefab (prefab parent)))
  30. (path (make-node-path parent name))
  31. (node (make-instance 'node
  32. :prefab prefab
  33. :name name
  34. :path path
  35. :data data
  36. :parent parent
  37. :merge-policy merge-policy)))
  38. (check/node-path-unused prefab path)
  39. (setf (fl.util:href (paths prefab) path) node)))
  40.  
  41. (defun find-node (path library-name &optional error-p)
  42. (let* ((prefab-name (first (explode-path path)))
  43. (prefab (find-prefab prefab-name library-name)))
  44. (or (fl.util:href (paths prefab) path)
  45. (when error-p
  46. (error "Node path ~s not found in prefab ~s." path prefab-name)))))
  47.  
  48. (defgeneric add-child (mode parent data &key &allow-other-keys))
  49.  
  50. (defmethod add-child ((mode (eql :new)) parent data &key target)
  51. (let* ((path-parts (explode-path target))
  52. (name (first path-parts))
  53. (new-data (rest (reduce #'list
  54. (butlast path-parts)
  55. :initial-value (cons (car (last path-parts)) data)
  56. :from-end t)))
  57. (child (make-node name new-data :parent parent)))
  58. (parse-prefab child new-data)))
  59.  
  60. (defmethod add-child ((mode (eql :copy)) parent data &key from source target)
  61. (check/mode-source mode parent source)
  62. (let ((source-data (data (find-node source from t))))
  63. (add-child :new parent source-data :target target)))
  64.  
  65. (defun make-link (source-path source-library target target-library)
  66. (let* ((source-node (find-node source-path source-library t))
  67. (target-key (cons target-library (path target))))
  68. (with-slots (%prefab %path) source-node
  69. (symbol-macrolet ((targets (fl.util:href (source->targets %prefab) %path)))
  70. (setf (fl.util:href (target->source %prefab) target-key) %path)
  71. (unless targets
  72. (setf targets (fl.util:dict #'equalp)))
  73. (setf (fl.util:href targets target-key) target)))))
  74.  
  75. (defmethod add-child ((mode (eql :link)) parent data &key from to source target)
  76. (check/mode-source mode parent source)
  77. (let* ((source-data (data (find-node source from t)))
  78. (child (add-child :new parent source-data :target target))
  79. (target (find-node (make-node-path parent target) to t)))
  80. (make-link source from target to)
  81. child))
  82.  
  83. #++(defmethod add-child ((mode (eql :link)) parent data &key source target)
  84. (check/mode-source mode parent source)
  85. (destructuring-bind (source-library source-path) source
  86. (let ((source-node (find-node source-path source-library t))
  87. (target-path (make-node-path parent target)))
  88. (with-slots (%prefab) source-node
  89. (with-slots (%target->source %source->targets) %prefab
  90. (let ((child (add-child :new parent (data source-node) :target target)))
  91. (make-link source-node)
  92. (setf (fl.util:href %target->source target-path) source-path)
  93. (make-source->target-link source-node target-path)
  94. child))))))
Add Comment
Please, Sign In to add comment