ObjectBuilder.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * ObjectBuilder.js
  3. *
  4. * @author realor
  5. */
  6. import { Solid } from '../core/Solid.js'
  7. import * as THREE from '../lib/three.module.js'
  8. class ObjectBuilder {
  9. static DEFAULT_INSTANCE = new ObjectBuilder()
  10. static classes = {} // builder registry
  11. constructor() {}
  12. /*
  13. * Calls action(dep) for each object dependency
  14. *
  15. * Traverse children by default
  16. */
  17. traverseDependencies(object, action) {
  18. const children = object.children
  19. for (let child of children) {
  20. action(child)
  21. }
  22. }
  23. /*
  24. * Updates the builder object references
  25. *
  26. * The builder must call update(refObject) for each direct reference
  27. * to a dependent object.
  28. *
  29. * The value returned by update(refObject) is the object that must be
  30. * replaced by refObject. When no replacement is required,
  31. * update(refObject) will return null.
  32. *
  33. * @returns {Boolean} true if any replacement has been done, false otherwise.
  34. *
  35. */
  36. updateReferences(object, update) {
  37. return false
  38. }
  39. /*
  40. * Builds object assuming its dependencies have already been built
  41. *
  42. * @returns {Boolean} true if object has actually changed, false othwerwise.
  43. */
  44. performBuild(object) {
  45. return false
  46. }
  47. /*
  48. * Tells whether this builder constructs the geometry of the object
  49. *
  50. * @returns {Boolean} true if this builder constructs the geometry,
  51. * false otherwise. By default, this method returns true.
  52. */
  53. isGeometryBuilder(object) {
  54. return true
  55. }
  56. /*
  57. * Tells whether this builder constructs the children of the object
  58. *
  59. * @returns {Boolean} true if this builder constructs the children of
  60. * the object, false otherwise. By default, this method returns false.
  61. */
  62. isChildrenBuilder(object) {
  63. return false
  64. }
  65. /*
  66. * Clones this builder
  67. *
  68. * @returns {ObjectBuilder} a clone of this builder
  69. */
  70. clone() {
  71. return new this.constructor().copy(this)
  72. }
  73. /*
  74. * Copies the parameters of the source builder to this builder
  75. *
  76. * @returns {ObjectBuilder} this builder
  77. */
  78. copy(source) {
  79. return this
  80. }
  81. /* static methods */
  82. static addClass(builderClass) {
  83. this.classes[builderClass.name] = builderClass
  84. }
  85. /* returns an array with the names of the builders of the given class */
  86. static getTypesOf(builderClass) {
  87. let types = []
  88. for (let className in this.classes) {
  89. let cls = this.classes[className]
  90. if (cls.prototype instanceof builderClass || cls === builderClass) {
  91. types.push(className)
  92. }
  93. }
  94. return types
  95. }
  96. static mark(object) {
  97. if (object.needsMarking === false) return
  98. object.needsMarking = false
  99. let builder = object.builder || ObjectBuilder.DEFAULT_INSTANCE
  100. builder.traverseDependencies(object, dep => {
  101. ObjectBuilder.mark(dep)
  102. object.needsRebuild = object.needsRebuild || dep.needsRebuild
  103. })
  104. }
  105. static build(object, built) {
  106. if (object.needsRebuild === false) return
  107. object.needsRebuild = false
  108. const builder = object.builder || ObjectBuilder.DEFAULT_INSTANCE
  109. builder.traverseDependencies(object, dep => {
  110. ObjectBuilder.build(dep, built)
  111. })
  112. if (builder.performBuild(object)) {
  113. if (built) built.push(object)
  114. }
  115. }
  116. static markAndBuild(object, built) {
  117. object.needsMarking = true
  118. object.traverse(child => (child.needsMarking = true))
  119. ObjectBuilder.mark(object)
  120. ObjectBuilder.build(object, built)
  121. }
  122. }
  123. export { ObjectBuilder }