Skip to content

Commit

Permalink
allow 'assignTo' to be assigned to multiple properties.
Browse files Browse the repository at this point in the history
  • Loading branch information
brianzinn committed Oct 23, 2020
1 parent 3806bc8 commit dc5daec
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/CreatedInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export type CustomProps = {
/**
* Assign to this property on the parent. Parent property is cleared on umnount.
*/
assignTo?: string
assignTo?: string | string[]
/**
* for VRExperienceHelper
*/
Expand Down
17 changes: 2 additions & 15 deletions src/customHosts/MaterialsLifecycleListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { CreatedInstance } from "../CreatedInstance"
import { LifecycleListener } from "../LifecycleListener"
import { Scene, AbstractMesh } from "@babylonjs/core"
import { Material } from '@babylonjs/core/Materials'
import { assignProperty } from "../helper/property"

export default class MaterialsLifecycleListener implements LifecycleListener<Material> {
onCreated(instance: CreatedInstance<Material>, scene: Scene) {
Expand Down Expand Up @@ -49,21 +50,7 @@ export default class MaterialsLifecycleListener implements LifecycleListener<Mat
while (tmp !== null) {
if (tmp.metadata && tmp.metadata.acceptsMaterials === true) {
if (instance.customProps.assignTo) {
const propsList: string[] = instance.customProps.assignTo.split('.');
let propToAssign = tmp.hostInstance;
propsList.forEach((prop: string, index: number) => {
if (propToAssign[prop] === undefined) {
// create property if it doesn't exist.
console.warn('Assign to created property', prop, 'on', propToAssign)
propToAssign[prop] = {}
}

if (index === propsList.length - 1) {
propToAssign[prop] = material;
} else {
propToAssign = propToAssign[prop]
}
})
assignProperty(material, tmp.hostInstance, instance.customProps.assignTo);
} else {
tmp.hostInstance.material = material
}
Expand Down
59 changes: 31 additions & 28 deletions src/helper/property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,43 @@
* @param propertyPath Where to assign value to on target (path to assign. ie: "baseTexture" or "mesh.material")
*
*/
export function assignProperty(value: any, target: any, propertyPath: string) {
const propsList: string[] = propertyPath.split('.');
export function assignProperty(value: any, target: any, propertyPath: string | string[]) {
const propertyPaths: string[] = Array.isArray(propertyPath) ? propertyPath : [propertyPath];
propertyPaths.forEach(propPath => {
const propsList: string[] = propPath.split('.');

propsList.forEach((prop: string, index: number) => {
// for assigning to arrays (ie: Texture to model -> meshes[1].material.albedoTexture)
const arrayRegex = /(?<arrayName>.*)\[(?<arrayIndexString>\d+)\]$/;
const match = prop.match(arrayRegex);
propsList.forEach((prop: string, index: number) => {
// for assigning to arrays (ie: Texture to model -> meshes[1].material.albedoTexture)
const arrayRegex = /(?<arrayName>.*)\[(?<arrayIndexString>\d+)\]$/;
const match = prop.match(arrayRegex);

if (match && (match as any).groups) {
const { arrayName, arrayIndexString} = (match as any).groups;
const arrayIndex = parseInt(arrayIndexString);
const arrayProp = target[arrayName];
if (arrayProp === undefined || !Array.isArray(arrayProp) || arrayIndex >= arrayProp.length ) {
console.error(`Array not found or missing index (skipping) for property assignment: '${arrayName}[${arrayIndex}]'`, target);
if (match && (match as any).groups) {
const { arrayName, arrayIndexString} = (match as any).groups;
const arrayIndex = parseInt(arrayIndexString);
const arrayProp = target[arrayName];
if (arrayProp === undefined || !Array.isArray(arrayProp) || arrayIndex >= arrayProp.length ) {
console.error(`Array not found or missing index (skipping) for property assignment: '${arrayName}[${arrayIndex}]'`, target);
} else {
if (index === propsList.length - 1) {
arrayProp[arrayIndex] = value;
} else {
target = arrayProp[arrayIndex];
}
}
} else {
if (target[prop] === undefined) {
// create property if it doesn't exist.
console.warn(`Created property ${prop} on: (from ${propsList})`, target)
target[prop] = {}
}

if (index === propsList.length - 1) {
arrayProp[arrayIndex] = value;
target[prop] = value;
} else {
target = arrayProp[arrayIndex];
target = target[prop]
}
}
} else {
if (target[prop] === undefined) {
// create property if it doesn't exist.
console.warn(`Created property ${prop} on: (from ${propsList})`, target)
target[prop] = {}
}

if (index === propsList.length - 1) {
target[prop] = value;
} else {
target = target[prop]
}
}
})
})
});
}

0 comments on commit dc5daec

Please sign in to comment.