Skip to content

Commit

Permalink
Revert "Revert "style system separation, clean up systems back to ECS" (
Browse files Browse the repository at this point in the history
#390)"

This reverts commit 5384ca7.
  • Loading branch information
michaelthatsit authored Feb 10, 2024
1 parent 5384ca7 commit e4ac8c8
Show file tree
Hide file tree
Showing 15 changed files with 303 additions and 215 deletions.
2 changes: 1 addition & 1 deletion dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body >
<mr-app debug="true">
<mr-app>
<mr-panel class="layout">
<mr-div id="navbar">
<mr-a href="https://volumetrics.io" target="_blank" class="company">
Expand Down
51 changes: 31 additions & 20 deletions dist/mr.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion samples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body >
<mr-app debug="true">
<mr-app>
<mr-panel class="layout">
<mr-div id="navbar">
<mr-a href="https://volumetrics.io" target="_blank" class="company">
Expand Down
7 changes: 5 additions & 2 deletions src/core/MRApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ import { MRSystem } from 'mrjs/core/MRSystem';
import { AnimationSystem } from 'mrjs/core/componentSystems/AnimationSystem';
import { ClippingSystem } from 'mrjs/core/componentSystems/ClippingSystem';
import { ControlSystem } from 'mrjs/core/componentSystems/ControlSystem';
import { GeometryStyleSystem } from 'mrjs/core/componentSystems/GeometryStyleSystem';
import { LayoutSystem } from 'mrjs/core/componentSystems/LayoutSystem';
import { MaskingSystem } from 'mrjs/core/componentSystems/MaskingSystem';
import { MaterialStyleSystem } from 'mrjs/core/componentSystems/MaterialStyleSystem';
import { PhysicsSystem } from 'mrjs/core/componentSystems/PhysicsSystem';
import { AnchorSystem } from 'mrjs/core/componentSystems/AnchorSystem';
import { SkyBoxSystem } from 'mrjs/core/componentSystems/SkyBoxSystem';
import { StyleSystem } from 'mrjs/core/componentSystems/StyleSystem';
import { TextSystem } from 'mrjs/core/componentSystems/TextSystem';
import { AudioSystem } from 'mrjs/core/componentSystems/AudioSystem';
import { PanelSystem } from 'mrjs/core/componentSystems/PanelSystem';
Expand Down Expand Up @@ -97,10 +98,12 @@ export class MRApp extends MRElement {
this.observer = new MutationObserver(this.mutationCallback);
this.observer.observe(this, { attributes: true, childList: true });

// order matters for all the below system creation items
this.panelSystem = new PanelSystem();
this.layoutSystem = new LayoutSystem();
this.textSystem = new TextSystem();
this.styleSystem = new StyleSystem();
this.geometryStyleSystem = new GeometryStyleSystem();
this.materialStyleSystem = new MaterialStyleSystem();
this.audioSystem = new AudioSystem();

// initialize built in Systems
Expand Down
84 changes: 2 additions & 82 deletions src/core/MRDivEntity.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,94 +110,14 @@ export class MRDivEntity extends MREntity {
this.background.geometry = mrjsUtils.geometry.UIPlane(this.width, this.height, [0], 18);
}

// TODO - can we move this to utils/Css.js ? ---- for border radius (which returns percentages instead of pixel values)
// leave here for now - to be moved after michael change
/**
* @function
* @description Converts the dom string to a 3D numerical value
* @param {string} val - the dom css information includes items of the form `XXXpx`, `XXX%`, etc
* @returns {number} - the 3D numerical represenation of the dom css value
*/
domToThree(val) {
if (typeof val === 'string') {
const valuepair = val.split(/(\d+(?:\.\d+)?)/).filter(Boolean);
if (valuepair.length > 1) {
switch (valuepair[1]) {
case 'px':
if (mrjsUtils.xr.isPresenting) {
return (val.split('px')[0] / global.appWidth) * mrjsUtils.app.scale;
}
return (val.split('px')[0] / global.appWidth) * global.viewPortWidth;
case '%':
if (mrjsUtils.xr.isPresenting) {
return (parseFloat(val) / 100) * mrjsUtils.app.scale;
}
return (parseFloat(val) / 100) * global.viewPortWidth;
default:
return val;
}
}
}
return val;
}

/**
*
*/
updateStyle() {
super.updateStyle();

// all div entities needs these steps
this.setBorder();
this.setBackground();
}

/**
* @function
* @description Calculates the border radius of the img based on the img tag in the shadow root
* @returns {number} - the resolved height
*/
get borderRadii() {
return this.compStyle.borderRadius.split(' ').map((r) => this.domToThree(r));
const borderRadii = this.compStyle.borderRadius.split(' ').map((r) => this.domToThree(r));
}

/**
* @function
* @description Sets the border of the UI based on compStyle and inputted css elements.
*/
setBorder() {
this.background.geometry = mrjsUtils.geometry.UIPlane(this.width, this.height, this.borderRadii, 18);
}

/**
* @function
* @description Sets the background based on compStyle and inputted css elements.
*/
setBackground() {
const color = this.compStyle.backgroundColor;
if (color.includes('rgba')) {
const rgba = color
.substring(5, color.length - 1)
.split(',')
.map((part) => parseFloat(part.trim()));
this.background.material.color.setStyle(`rgb(${rgba[0]}, ${rgba[1]}, ${rgba[2]})`);
if (rgba[3] == 0) {
this.background.visible = false;
} else {
this.background.material.transparent = true;
this.background.material.opacity = rgba[3];
this.background.visible = true;
}
} else {
this.background.material.color.setStyle(color);
this.background.visible = true;
}

if (this.compStyle.opacity < 1) {
this.background.material.opacity = this.compStyle.opacity;
}
this.background.material.needsUpdate = true;
return this.compStyle.borderRadius.split(' ').map((r) => mrjsUtils.css.domToThree(r));
const borderRadii = this.compStyle.borderRadius.split(' ').map((r) => mrjsUtils.css.domToThree(r));
}
}

Expand Down
104 changes: 101 additions & 3 deletions src/core/MREntity.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,50 @@ export class MREntity extends MRElement {
return this.size.y;
}

// undefined == always update, once set to true/false trigger, then updates based on that every frame
// setting back to undefined sets to always update.
_needsGeometryUpdate = false;

/**
* @function
* @description Checks if the system is setup to always run instead of being in a state that allows for toggling on and off.
* Useful for readability and to not need to check against undefined often.
* @returns {boolean} true if the internal _needsSystemUpdate is set to 'undefined', false otherwise.
*/
get alwaysNeedsGeometryUpdate() {
return this._needsGeometryUpdate === undefined;
}

/**
* @function
* @description Sets the system ito always run (true) or to be in a state that allows for toggling on and off (false).
* Useful for readability and to not need to check against undefined often.
*/
set alwaysNeedsGeometryUpdate(bool) {
this._needsGeometryUpdate = bool ? undefined : false;
}

/**
* @function
* @description Getter to checks if we need the StyleSystem to run on this entity during the current iteration.
* Default implementation returns true if the needsSystemUpdate flag has been set to true or is in the alwaysNeedsSystemUpdate state.
* Allows subclasses to override with their own implementation.
* @returns {boolean} true if the system is in a state where this system is needed to update, false otherwise
*/
get needsGeometryUpdate() {
return this.alwaysNeedsGeometryUpdate || this._needsGeometryUpdate;
}

/**
* @function
* @description Set the needsStyleUpdate parameter.
* undefined - means the StyleSystem will update this entity's style every time the application loops.
* true/false - means the StyleSystem will update this entity's style only running one iteration when set to true and then reset back to false waiting for the next trigger.
*/
set needsGeometryUpdate(bool) {
this._needsGeometryUpdate = bool;
}

// undefined == always update, once set to true/false trigger, then updates based on that every frame
// setting back to undefined sets to always update.
_needsStyleUpdate = false;
Expand All @@ -123,6 +167,15 @@ export class MREntity extends MRElement {
return this._needsStyleUpdate === undefined;
}

/**
* @function
* @description Sets the system ito always run (true) or to be in a state that allows for toggling on and off (false).
* Useful for readability and to not need to check against undefined often.
*/
set alwaysNeedsStyleUpdate(bool) {
this._needsStyleUpdate = bool ? undefined : false;
}

/**
* @function
* @description Getter to checks if we need the StyleSystem to run on this entity during the current iteration.
Expand All @@ -145,10 +198,16 @@ export class MREntity extends MRElement {
}

/**
* @function
* @description
* @function
* @description Inside the engine's ECS these arent filled in, theyre directly in the system themselves - but they can be overwritten by others when they create new entities
*/
updateMaterialStyle() {}

/**
* @function
* @description Inside the engine's ECS these arent filled in, theyre directly in the system themselves - but they can be overwritten by others when they create new entities
*/
updateStyle() {}
updateGeometryStyle() {}

/**
* @function
Expand Down Expand Up @@ -207,6 +266,9 @@ export class MREntity extends MRElement {

document.addEventListener('DOMContentLoaded', (event) => {
this.loadAttributes();
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
Expand All @@ -215,68 +277,101 @@ export class MREntity extends MRElement {

document.addEventListener('engine-started', (event) => {
this.dispatchEvent(new CustomEvent('new-entity', { bubbles: true }));
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
});

MOUSE_EVENTS.forEach((eventType) => {
this.addEventListener(eventType, (event) => {
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
});
});

this.addEventListener('touch-start', (event) => {
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
this.onTouch(event);
});
this.addEventListener('touch', (event) => {
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
this.onTouch(event);
});
this.addEventListener('touch-end', (event) => {
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
this.onTouch(event);
});
this.addEventListener('hover-start', (event) => {
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
this.onHover(event);
});
this.addEventListener('hover-end', (event) => {
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
this.onHover(event);
});

this.addEventListener('child-updated', (event) => {
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
});

window.addEventListener('resize', (event) => {
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
});

document.addEventListener('enterXR', (event) => {
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
});
document.addEventListener('exitXR', (event) => {
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
Expand Down Expand Up @@ -363,6 +458,9 @@ export class MREntity extends MRElement {

switch (mutation.type) {
case 'childList':
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
Expand Down
9 changes: 9 additions & 0 deletions src/core/MRTextEntity.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,18 @@ export class MRTextEntity extends MRDivEntity {
// This event listener is added so anytime a panel changes (resize, etc), the text changes
// accordingly
document.addEventListener('panel-mutated', () => {
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
});

document.addEventListener('font-loaded', () => {
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
Expand All @@ -47,6 +53,9 @@ export class MRTextEntity extends MRDivEntity {
connected() {
const text = this.textContent.trim();
this.textObj.text = text.length > 0 ? text : ' ';
if (!this.alwaysNeedsGeometryUpdate) {
this.needsGeometryUpdate = true;
}
if (!this.alwaysNeedsStyleUpdate) {
this.needsStyleUpdate = true;
}
Expand Down
6 changes: 5 additions & 1 deletion src/core/componentSystems/GeometryStyleSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ export class GeometryStyleSystem extends MRSystem {
}

setScale(entity) {
entity.object3D.scale.setScalar(entity.compStyle.scale != 'none' ? parseFloat(entity.compStyle.scale) * mrjsUtils.app.scale : 1);
entity.object3D.scale.setScalar(
entity.compStyle.scale != 'none'
? parseFloat(entity.compStyle.scale) * mrjsUtils.app.scale
: 1
);
}

/**
Expand Down
Loading

0 comments on commit e4ac8c8

Please sign in to comment.