@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
220 lines (181 loc) • 4.69 kB
JavaScript
import { assert } from "../../../core/assert.js";
import { combine_hash } from "../../../core/collection/array/combine_hash.js";
import Vector2 from '../../../core/geom/Vector2.js';
import { objectDeepEquals } from "../../../core/model/object/objectDeepEquals.js";
import ObservedBoolean from "../../../core/model/ObservedBoolean.js";
import { computeStringHash } from "../../../core/primitives/strings/computeStringHash.js";
/**
*
* @enum {number}
*/
export const GUIElementFlag = {
/**
* If this is set to false GUI element's view will not be managed by the system
*/
Managed: 1,
/**
* Whether or not underlying view has been initialized
*/
Initialized: 2
};
class GUIElement {
/**
*
* @type {View}
*/
view = null;
/**
*
* @type {String}
*/
klass = null;
/**
*
* @type {Object}
*/
parameters = {};
/**
* ranges from 0..1 in both X and Y, controls anchor point of element positioning
* @type {Vector2}
*/
anchor = new Vector2(0, 0);
/**
* Used for visual grouping of elements, system will create and manage named containers to group elements together
* @readonly
* @type {String|null}
*/
group = null;
/**
* @private
* @type {number}
*/
flags = GUIElementFlag.Managed;
/**
*
* @type {ObservedBoolean}
*/
visible = new ObservedBoolean(true);
/**
*
* @param {number|GUIElementFlag} flag
* @returns {void}
*/
setFlag(flag) {
this.flags |= flag;
}
/**
*
* @param {number|GUIElementFlag} flag
* @returns {void}
*/
clearFlag(flag) {
this.flags &= ~flag;
}
/**
*
* @param {number|GUIElementFlag} flag
* @param {boolean} value
*/
writeFlag(flag, value) {
if (value) {
this.setFlag(flag);
} else {
this.clearFlag(flag);
}
}
/**
*
* @param {number|GUIElementFlag} flag
* @returns {boolean}
*/
getFlag(flag) {
return (this.flags & flag) === flag;
}
/**
*
* @param {GUIElement} other
* @returns {boolean}
*/
equals(other) {
if (this.flags !== other.flags) {
return false;
}
if (this.klass !== other.klass) {
return false;
}
if (!this.getFlag(GUIElementFlag.Managed) && this.view !== other.view) {
return false;
}
if (!this.anchor.equals(other.anchor)) {
return false;
}
if (this.group !== other.group) {
return false;
}
if (!this.visible.equals(other.visible)) {
return false;
}
if (!objectDeepEquals(this.parameters, other.parameters)) {
return false;
}
return true;
}
/**
*
* @return {number}
*/
hash() {
return combine_hash(
this.flags,
computeStringHash(this.klass),
this.anchor.hash(),
computeStringHash(this.group),
this.visible.hash()
)
}
/**
*
* @param {View} view
* @returns {GUIElement}
*/
static fromView(view) {
assert.defined(view, 'view');
assert.notNull(view, 'view');
const r = new GUIElement();
r.clearFlag(GUIElementFlag.Managed);
r.view = view;
return r;
}
/**
*
* @param j
* @return {GUIElement}
*/
static fromJSON(j) {
const r = new GUIElement();
r.fromJSON(j);
return r;
}
fromJSON({ klass, parameters = {}, anchor = Vector2.zero, group = null, visible = true }) {
if (group !== null && typeof group !== "string") {
throw new Error(`Expected group to be null or string, instead was '${typeof group}'`);
}
this.klass = klass;
this.parameters = parameters;
this.anchor.fromJSON(anchor);
this.group = group;
this.visible.set(visible);
}
toJSON() {
return {
klass: this.klass,
parameters: this.parameters,
anchor: this.anchor.toJSON(),
group: this.group,
visible: this.visible.toJSON()
};
}
}
GUIElement.typeName = "GUIElement";
GUIElement.serializable = true;
export default GUIElement;