action.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. import { Observable } from "../Misc/observable.js";
  2. import { Vector2, Vector3 } from "../Maths/math.vector.js";
  3. import { Color3, Color4 } from "../Maths/math.color.js";
  4. import { RegisterClass } from "../Misc/typeStore.js";
  5. /**
  6. * The action to be carried out following a trigger
  7. * @see https://doc.babylonjs.com/features/featuresDeepDive/events/actions#available-actions
  8. */
  9. export class Action {
  10. /**
  11. * Creates a new Action
  12. * @param triggerOptions the trigger, with or without parameters, for the action
  13. * @param condition an optional determinant of action
  14. */
  15. constructor(
  16. /** the trigger, with or without parameters, for the action */
  17. triggerOptions, condition) {
  18. this.triggerOptions = triggerOptions;
  19. /**
  20. * An event triggered prior to action being executed.
  21. */
  22. this.onBeforeExecuteObservable = new Observable();
  23. if (triggerOptions.parameter) {
  24. this.trigger = triggerOptions.trigger;
  25. this._triggerParameter = triggerOptions.parameter;
  26. }
  27. else if (triggerOptions.trigger) {
  28. this.trigger = triggerOptions.trigger;
  29. }
  30. else {
  31. this.trigger = triggerOptions;
  32. }
  33. this._nextActiveAction = this;
  34. this._condition = condition;
  35. }
  36. /**
  37. * Internal only
  38. * @internal
  39. */
  40. _prepare() { }
  41. /**
  42. * Gets the trigger parameter
  43. * @returns the trigger parameter
  44. */
  45. getTriggerParameter() {
  46. return this._triggerParameter;
  47. }
  48. /**
  49. * Sets the trigger parameter
  50. * @param value defines the new trigger parameter
  51. */
  52. setTriggerParameter(value) {
  53. this._triggerParameter = value;
  54. }
  55. /**
  56. * Internal only - Returns if the current condition allows to run the action
  57. * @internal
  58. */
  59. _evaluateConditionForCurrentFrame() {
  60. const condition = this._condition;
  61. if (!condition) {
  62. return true;
  63. }
  64. const currentRenderId = this._actionManager.getScene().getRenderId();
  65. // We cache the current evaluation for the current frame
  66. if (condition._evaluationId !== currentRenderId) {
  67. condition._evaluationId = currentRenderId;
  68. condition._currentResult = condition.isValid();
  69. }
  70. return condition._currentResult;
  71. }
  72. /**
  73. * Internal only - executes current action event
  74. * @internal
  75. */
  76. _executeCurrent(evt) {
  77. const isConditionValid = this._evaluateConditionForCurrentFrame();
  78. if (!isConditionValid) {
  79. return;
  80. }
  81. this.onBeforeExecuteObservable.notifyObservers(this);
  82. this._nextActiveAction.execute(evt);
  83. this.skipToNextActiveAction();
  84. }
  85. /**
  86. * Execute placeholder for child classes
  87. * @param evt optional action event
  88. */
  89. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  90. execute(evt) { }
  91. /**
  92. * Skips to next active action
  93. */
  94. skipToNextActiveAction() {
  95. if (this._nextActiveAction._child) {
  96. if (!this._nextActiveAction._child._actionManager) {
  97. this._nextActiveAction._child._actionManager = this._actionManager;
  98. }
  99. this._nextActiveAction = this._nextActiveAction._child;
  100. }
  101. else {
  102. this._nextActiveAction = this;
  103. }
  104. }
  105. /**
  106. * Adds action to chain of actions, may be a DoNothingAction
  107. * @param action defines the next action to execute
  108. * @returns The action passed in
  109. * @see https://www.babylonjs-playground.com/#1T30HR#0
  110. */
  111. then(action) {
  112. this._child = action;
  113. action._actionManager = this._actionManager;
  114. action._prepare();
  115. return action;
  116. }
  117. /**
  118. * Internal only
  119. * @internal
  120. */
  121. _getProperty(propertyPath) {
  122. return this._actionManager._getProperty(propertyPath);
  123. }
  124. /**
  125. * @internal
  126. */
  127. _getEffectiveTarget(target, propertyPath) {
  128. return this._actionManager._getEffectiveTarget(target, propertyPath);
  129. }
  130. /**
  131. * Serialize placeholder for child classes
  132. * @param parent of child
  133. * @returns the serialized object
  134. */
  135. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  136. serialize(parent) {
  137. return null;
  138. }
  139. /**
  140. * Internal only called by serialize
  141. * @internal
  142. */
  143. _serialize(serializedAction, parent) {
  144. const serializationObject = {
  145. type: 1,
  146. children: [],
  147. name: serializedAction.name,
  148. properties: serializedAction.properties || [],
  149. };
  150. // Serialize child
  151. if (this._child) {
  152. this._child.serialize(serializationObject);
  153. }
  154. // Check if "this" has a condition
  155. if (this._condition) {
  156. const serializedCondition = this._condition.serialize();
  157. serializedCondition.children.push(serializationObject);
  158. if (parent) {
  159. parent.children.push(serializedCondition);
  160. }
  161. return serializedCondition;
  162. }
  163. if (parent) {
  164. parent.children.push(serializationObject);
  165. }
  166. return serializationObject;
  167. }
  168. }
  169. /**
  170. * Internal only
  171. * @internal
  172. */
  173. Action._SerializeValueAsString = (value) => {
  174. if (typeof value === "number") {
  175. return value.toString();
  176. }
  177. if (typeof value === "boolean") {
  178. return value ? "true" : "false";
  179. }
  180. if (value instanceof Vector2) {
  181. return value.x + ", " + value.y;
  182. }
  183. if (value instanceof Vector3) {
  184. return value.x + ", " + value.y + ", " + value.z;
  185. }
  186. if (value instanceof Color3) {
  187. return value.r + ", " + value.g + ", " + value.b;
  188. }
  189. if (value instanceof Color4) {
  190. return value.r + ", " + value.g + ", " + value.b + ", " + value.a;
  191. }
  192. return value; // string
  193. };
  194. /**
  195. * Internal only
  196. * @internal
  197. */
  198. Action._GetTargetProperty = (target) => {
  199. return {
  200. name: "target",
  201. targetType: target._isMesh
  202. ? "MeshProperties"
  203. : target._isLight
  204. ? "LightProperties"
  205. : target._isCamera
  206. ? "CameraProperties"
  207. : target._isMaterial
  208. ? "MaterialProperties"
  209. : "SceneProperties",
  210. value: target._isScene ? "Scene" : target.name,
  211. };
  212. };
  213. RegisterClass("BABYLON.Action", Action);
  214. //# sourceMappingURL=action.js.map