src/lib/descriptors/ModuleDescriptor.js
import ReactPropTypeLocationNames from 'react/lib/ReactPropTypeLocationNames';
import THREEElementDescriptor from './THREEElementDescriptor';
import Module from '../Module';
import PropTypeError from '../utils/PropTypeError';
// Returns class name of the object, if any.
// Used for the subclass proptype checker
function getClassName(propValue) {
if (!propValue.constructor || !propValue.constructor.name) {
return '<<anonymous>>';
}
return propValue.constructor.name;
}
class ModuleDescriptor extends THREEElementDescriptor {
constructor(react3RendererInstance) {
super(react3RendererInstance);
const moduleSubclassValidator = (props, propName, componentName, location, propFullName) => {
const locationName = ReactPropTypeLocationNames[location];
if (!props[propName]) {
return new PropTypeError(
`The ${locationName} \`${propFullName}\` is marked as required in ` +
`\`${componentName}\`, but its value is \`undefined\`.`
);
}
if (!(props[propName].prototype instanceof Module)) {
const actualClassName = getClassName(props[propName]);
return new PropTypeError(`Invalid ${locationName} \`${propFullName}\` ` +
`of type \`${actualClassName}\` supplied to \`${componentName}\`, ` +
'expected subclass of `Module`.');
}
// success returns undefined
return undefined;
};
moduleSubclassValidator.toString = () =>
`${'```'} subclass of ReactThreeRenderer.Module ${'```'} *${'```'} required ${'```'}*`;
this.hasProp('descriptor', {
type: moduleSubclassValidator,
update: this.triggerRemount,
default: undefined,
});
}
construct(props) {
// going insane here but... let's... just do this.
const ModuleClass = props.descriptor;
return new ModuleClass();
}
applyInitialProps(threeObject, props) {
super.applyInitialProps(threeObject, props);
threeObject.setup(this.react3RendererInstance);
}
unmount(threeObject) {
threeObject.dispose();
super.unmount(threeObject);
}
}
module.exports = ModuleDescriptor;