whs
Version:
Super-fast 3D framework for Web Applications & Games. Based on Three.js
1,720 lines (1,428 loc) • 459 kB
JavaScript
/* WhitestormJS Framework v2.1.9 */
import { AdditiveBlending, AmbientLight, AnimationClip, AnimationMixer, BoxBufferGeometry, BoxGeometry, BufferAttribute, BufferGeometry, CircleBufferGeometry, CircleGeometry, Clock, Color, ConeBufferGeometry, ConeGeometry, CubeCamera, CylinderBufferGeometry, CylinderGeometry, DataTexture, DepthStencilFormat, DepthTexture, DirectionalLight, DodecahedronBufferGeometry, DodecahedronGeometry, EventDispatcher, ExtrudeGeometry, FloatType, Fog, FogExp2, Font, FontLoader, Geometry, HemisphereLight, IcosahedronBufferGeometry, IcosahedronGeometry, JSONLoader, LatheBufferGeometry, LatheGeometry, Line, LineCurve3, LinearFilter, LinearMipMapLinearFilter, MOUSE, Mesh, MeshBasicMaterial, NearestFilter, Object3D, OctahedronBufferGeometry, OctahedronGeometry, OrthographicCamera, ParametricBufferGeometry, ParametricGeometry, PerspectiveCamera, Plane, PlaneBufferGeometry, PlaneGeometry, PointLight, PolyhedronBufferGeometry, PolyhedronGeometry, Quaternion, REVISION, RGBAFormat, RGBFormat, Raycaster, RectAreaLight, RepeatWrapping, RingBufferGeometry, RingGeometry, Scene, ShaderMaterial, ShapeBufferGeometry, ShapeGeometry, SkinnedMesh, SphereBufferGeometry, SphereGeometry, Spherical, SpotLight, TetrahedronBufferGeometry, TetrahedronGeometry, TextGeometry, Texture, TextureLoader, TorusGeometry, TorusKnotBufferGeometry, TorusKnotGeometry, TubeBufferGeometry, TubeGeometry, UVMapping, Uniform, UnsignedInt248Type, Vector2, Vector3, Vector4, WebGLRenderTarget, WebGLRenderer } from 'three';
var extend = function extend(object) {
for (var _len = arguments.length, extensions = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
extensions[_key - 1] = arguments[_key];
}
// $.extend alternative, ... is the spread operator.
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = extensions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var extension = _step.value;
// console.log(extension);
// console.log(typeof extension);
if (!extension) continue; // Ignore null and undefined objects and parameters.
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = Object.getOwnPropertyNames(extension)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var prop = _step2.value;
// Do not traverse the prototype chain.
if (object[prop] !== undefined && extension[prop] && object[prop].toString() === '[object Object]' && extension[prop].toString() === '[object Object]') {
// Goes deep only if object[prop] and extension[prop] are both objects !
if (object[prop].constructor === Object) extend(object[prop], extension[prop]);
} else object[prop] = typeof object[prop] === 'undefined' ? extension[prop] : object[prop];
if (typeof object[prop] === 'undefined' && Array.isArray(extension[prop])) object[prop] = extension[prop].slice(); // Add values that do not already exist.
else if (typeof object[prop] === 'undefined' && Array.isArray(extension[prop])) object[prop] = extension[prop];
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return object;
};
var instruct = function instruct(array, instArray) {
var tempObject = {};
for (var i = 0, max = instArray.length; i < max; i++) {
var guide = instArray[i];
tempObject[guide] = array[i];
}
return tempObject;
};
var transformData = function transformData(object, instructions) {
for (var key in instructions) {
if (Array.isArray(object[key])) object[key] = instruct(object[key], instructions[key]);else if (object[key] instanceof Object && !Array.isArray(instructions[key])) object[key] = transformData(object[key], instructions[key]);
}
return object;
};
var toArray = function toArray(object, instruction) {
var tempArray = [];
for (var i = 0, max = instruction.length; i < max; i++) {
var guide = instruction[i];
tempArray[i] = object[guide];
}
return tempArray;
};
var minivents_commonjs = function Events(target){
var events = {}, empty = [];
target = target || this;
/**
* On: listen to events
*/
target.on = function(type, func, ctx){
(events[type] = events[type] || []).push([func, ctx]);
};
/**
* Off: stop listening to event / specific callback
*/
target.off = function(type, func){
type || (events = {});
var list = events[type] || empty,
i = list.length = func ? list.length : 0;
while(i--) func == list[i][0] && list.splice(i,1);
};
/**
* Emit: send event, callbacks will be triggered
*/
target.emit = function(type){
var e = events[type] || empty, list = e.length > 0 ? e.slice(0, e.length) : e, i=0, j;
while(j=list[i++]) j[0].apply(j[1], empty.slice.call(arguments, 1));
};
};
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var defineProperty = function (obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
};
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var get = function get(object, property, receiver) {
if (object === null) object = Function.prototype;
var desc = Object.getOwnPropertyDescriptor(object, property);
if (desc === undefined) {
var parent = Object.getPrototypeOf(object);
if (parent === null) {
return undefined;
} else {
return get(parent, property, receiver);
}
} else if ("value" in desc) {
return desc.value;
} else {
var getter = desc.get;
if (getter === undefined) {
return undefined;
}
return getter.call(receiver);
}
};
var inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
var slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
var CompositionError = function (_Error) {
inherits(CompositionError, _Error);
function CompositionError(classInstance, message, component) {
classCallCheck(this, CompositionError);
var _this = possibleConstructorReturn(this, (CompositionError.__proto__ || Object.getPrototypeOf(CompositionError)).call(this, '@' + classInstance + ': ' + message));
var stackArray = _this.stack.split('\n');
stackArray.splice(1, 2);
_this.stack = stackArray.join('\n');
if (console) console.error('Component:', component);
_this.name = 'CompositionError';
return _this;
}
return CompositionError;
}(Error);
var DependencyError = function (_Error2) {
inherits(DependencyError, _Error2);
function DependencyError(classInstance, message, activeModule) {
var dependencyModule = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
classCallCheck(this, DependencyError);
var _this2 = possibleConstructorReturn(this, (DependencyError.__proto__ || Object.getPrototypeOf(DependencyError)).call(this, '@' + classInstance + ': ' + message));
var stackArray = _this2.stack.split('\n');
stackArray.splice(1, 2);
_this2.stack = stackArray.join('\n');
if (console) console.error('Active module:', activeModule);
if (console && dependencyModule) console.error('Dependency published by module:', dependencyModule);
_this2.name = 'DependencyError';
return _this2;
}
return DependencyError;
}(Error);
var ManagerError = function (_Error3) {
inherits(ManagerError, _Error3);
function ManagerError(classInstance, message, component) {
var activeModule = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
classCallCheck(this, ManagerError);
var _this3 = possibleConstructorReturn(this, (ManagerError.__proto__ || Object.getPrototypeOf(ManagerError)).call(this, '@' + classInstance + ': ' + message));
var stackArray = _this3.stack.split('\n');
stackArray.splice(1, 2);
_this3.stack = stackArray.join('\n');
if (console) console.error('Component:', component);
if (console && activeModule) console.error('Active module:', activeModule);
_this3.name = 'ManagerError';
return _this3;
}
return ManagerError;
}(Error);
// Check for Three.js
var warnDeps = function warnDeps() {
throw new Error('WhitestormJS Framework requires Three.js r84. https://threejs.org/');
};
try {
if (!REVISION) warnDeps();
} catch (err) {
warnDeps();
}
/**
* @class ModuleSystem
* @category core
* @description Provides API for classes that will use Modules.<br/>
* This class includes basic event system with those supported methods:
* <pre>.on()</pre><pre>.off()</pre><pre>.emit()</pre>
* @extends Events
* @memberof module:core
*/
var ModuleSystem = function (_Events) {
inherits(ModuleSystem, _Events);
function ModuleSystem() {
classCallCheck(this, ModuleSystem);
return possibleConstructorReturn(this, (ModuleSystem.__proto__ || Object.getPrototypeOf(ModuleSystem)).apply(this, arguments));
}
createClass(ModuleSystem, [{
key: 'integrateModules',
// INTEGRATING
/**
* @method integrateModules
* @instance
* @description This method applies all modules from .modules collection.
* @param {Object} [source] If source (should be a component) is provided, will replace .modules with source's one before executing modules.
* @memberof module:core.ModuleSystem
*/
value: function integrateModules(source) {
if (!this.modules && !source) return;
if (source && source.modules) this.modules = source.modules.slice(0);
if (this.modules) {
for (var i = 0, max = this.modules.length; i < max; i++) {
this.applyModule(this.modules[i], false);
}
}
if (source) this.applyBridge({ onCopy: source });
}
// APPLYING MODULE (...and a "bridge" for module)
/**
* @method applyBridge
* @instance
* @description Makes component-specific API to work with modules.
* @param {Object} bridgeMap
* @return {Object} Returns object with modified values.
* @memberof module:core.ModuleSystem
*/
}, {
key: 'applyBridge',
value: function applyBridge() {
var bridgeMap = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var modules = this.modules;
if (!modules) return bridgeMap;
for (var i = 0, max = modules.length; i < max; i++) {
for (var key in bridgeMap) {
if (bridgeMap[key]) {
var module = modules[i];
if (module && module.bridge && module.bridge[key]) bridgeMap[key] = module.bridge[key].apply(this, [bridgeMap[key], module]);
}
}
}
return bridgeMap;
}
/**
* @method applyCommand
* @instance
* @description .applyCommand runs a method called `name` on all modules.
* @param {String} name the method name.
* @param {Function} [cb=(func, moduleScope) => func.apply(this, [moduleScope])] How the function is wrapped/
* @memberof module:core.ModuleSystem
*/
}, {
key: 'applyCommand',
value: function applyCommand(name) {
var _this2 = this;
var cb = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (func, moduleScope) {
return func.apply(_this2, [moduleScope]);
};
var modules = this.modules;
if (!modules) return;
for (var i = 0, max = modules.length; i < max; i++) {
var module = modules[i];
if (name in module) cb(module[name], module);
}
}
/**
* @method applyModule
* @instance
* @description .applyModule is also used in .integrateModules() function.
* It does exactly what its name says (applies module to component or app).
* @param {Object} module the module to apply
* @param {Boolean} [push=true]
* @return {Object} Returns module that was applied.
* @throws {ManagerError}
* @memberof module:core.ModuleSystem
*/
}, {
key: 'applyModule',
value: function applyModule(module) {
var push = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
if (!module) return;
if (push && this.modules) this.modules.push(module);else if (push) this.modules = [module];
if (this.manager) this.manager.active(module);
if (module.manager && this.manager) module.manager(this.manager);else if (module.manager) {
throw new ManagerError('Component', 'Module requires ModuleManager that is turned off for this component', this, module);
}
if (module.integrate) module.integrate.bind(this)(module);
return module;
}
/**
* @method disposeModules
* @instance
* @description Disposes of all modules
* @memberof module:core.ModuleSystem
*/
}, {
key: 'disposeModules',
value: function disposeModules() {
while (this.modules.length) {
this.disposeModule(this.modules[0]);
}
}
/**
* @method disposeModule
* @instance
* @description Disposes of the given module
* @param {Object} module the module to dispose
* @return {Module} Returns module that was removed.
* @memberof module:core.ModuleSystem
*/
}, {
key: 'disposeModule',
value: function disposeModule(module) {
if (!module) return;
this.modules.splice(this.modules.indexOf(module), 1);
if (module.dispose) module.dispose.bind(this)(module);
return module;
}
// PIPED METHOD
/**
* @method module
* @instance
* @description piped version of .applyModule().
* @param {Object} module the module to apply
* @return {this} returns this - app/component
* @throws {ManagerError}
* @memberof module:core.ModuleSystem
* @example <caption>Piped modules</caption>
* component
* .module(new Module1())
* .module(new Module2())
* .module(new Module3())
*/
}, {
key: 'module',
value: function module(_module) {
this.applyModule(_module);
return this;
}
}]);
return ModuleSystem;
}(minivents_commonjs);
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/** Built-in value references. */
var Symbol$1 = root.Symbol;
/** Used for built-in method references. */
var objectProto$1 = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty$1 = objectProto$1.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto$1.toString;
/** Built-in value references. */
var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined;
/**
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the raw `toStringTag`.
*/
function getRawTag(value) {
var isOwn = hasOwnProperty$1.call(value, symToStringTag$1),
tag = value[symToStringTag$1];
try {
value[symToStringTag$1] = undefined;
var unmasked = true;
} catch (e) {}
var result = nativeObjectToString.call(value);
if (unmasked) {
if (isOwn) {
value[symToStringTag$1] = tag;
} else {
delete value[symToStringTag$1];
}
}
return result;
}
/** Used for built-in method references. */
var objectProto$2 = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString$1 = objectProto$2.toString;
/**
* Converts `value` to a string using `Object.prototype.toString`.
*
* @private
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
*/
function objectToString(value) {
return nativeObjectToString$1.call(value);
}
/** `Object#toString` result references. */
var nullTag = '[object Null]';
var undefinedTag = '[object Undefined]';
/** Built-in value references. */
var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined;
/**
* The base implementation of `getTag` without fallbacks for buggy environments.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function baseGetTag(value) {
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
return (symToStringTag && symToStringTag in Object(value))
? getRawTag(value)
: objectToString(value);
}
/**
* Creates a unary function that invokes `func` with its argument transformed.
*
* @private
* @param {Function} func The function to wrap.
* @param {Function} transform The argument transform.
* @returns {Function} Returns the new function.
*/
function overArg(func, transform) {
return function(arg) {
return func(transform(arg));
};
}
/** Built-in value references. */
var getPrototype = overArg(Object.getPrototypeOf, Object);
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return value != null && typeof value == 'object';
}
/** `Object#toString` result references. */
var objectTag = '[object Object]';
/** Used for built-in method references. */
var funcProto = Function.prototype;
var objectProto = Object.prototype;
/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/** Used to infer the `Object` constructor. */
var objectCtorString = funcToString.call(Object);
/**
* Checks if `value` is a plain object, that is, an object created by the
* `Object` constructor or one with a `[[Prototype]]` of `null`.
*
* @static
* @memberOf _
* @since 0.8.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
* @example
*
* function Foo() {
* this.a = 1;
* }
*
* _.isPlainObject(new Foo);
* // => false
*
* _.isPlainObject([1, 2, 3]);
* // => false
*
* _.isPlainObject({ 'x': 0, 'y': 0 });
* // => true
*
* _.isPlainObject(Object.create(null));
* // => true
*/
function isPlainObject(value) {
if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
return false;
}
var proto = getPrototype(value);
if (proto === null) {
return true;
}
var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
return typeof Ctor == 'function' && Ctor instanceof Ctor &&
funcToString.call(Ctor) == objectCtorString;
}
function symbolObservablePonyfill(root) {
var result;
var Symbol = root.Symbol;
if (typeof Symbol === 'function') {
if (Symbol.observable) {
result = Symbol.observable;
} else {
result = Symbol('observable');
Symbol.observable = result;
}
} else {
result = '@@observable';
}
return result;
}
/* global window */
var root$2;
if (typeof self !== 'undefined') {
root$2 = self;
} else if (typeof window !== 'undefined') {
root$2 = window;
} else if (typeof global !== 'undefined') {
root$2 = global;
} else if (typeof module !== 'undefined') {
root$2 = module;
} else {
root$2 = Function('return this')();
}
var result = symbolObservablePonyfill(root$2);
/**
* These are private action types reserved by Redux.
* For any unknown actions, you must return the current state.
* If the current state is undefined, you must return the initial state.
* Do not reference these action types directly in your code.
*/
var ActionTypes = {
INIT: '@@redux/INIT'
/**
* Creates a Redux store that holds the state tree.
* The only way to change the data in the store is to call `dispatch()` on it.
*
* There should only be a single store in your app. To specify how different
* parts of the state tree respond to actions, you may combine several reducers
* into a single reducer function by using `combineReducers`.
*
* @param {Function} reducer A function that returns the next state tree, given
* the current state tree and the action to handle.
*
* @param {any} [preloadedState] The initial state. You may optionally specify it
* to hydrate the state from the server in universal apps, or to restore a
* previously serialized user session.
* If you use `combineReducers` to produce the root reducer function, this must be
* an object with the same shape as `combineReducers` keys.
*
* @param {Function} [enhancer] The store enhancer. You may optionally specify it
* to enhance the store with third-party capabilities such as middleware,
* time travel, persistence, etc. The only store enhancer that ships with Redux
* is `applyMiddleware()`.
*
* @returns {Store} A Redux store that lets you read the state, dispatch actions
* and subscribe to changes.
*/
};function createStore(reducer, preloadedState, enhancer) {
var _ref2;
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
enhancer = preloadedState;
preloadedState = undefined;
}
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.');
}
return enhancer(createStore)(reducer, preloadedState);
}
if (typeof reducer !== 'function') {
throw new Error('Expected the reducer to be a function.');
}
var currentReducer = reducer;
var currentState = preloadedState;
var currentListeners = [];
var nextListeners = currentListeners;
var isDispatching = false;
function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice();
}
}
/**
* Reads the state tree managed by the store.
*
* @returns {any} The current state tree of your application.
*/
function getState() {
return currentState;
}
/**
* Adds a change listener. It will be called any time an action is dispatched,
* and some part of the state tree may potentially have changed. You may then
* call `getState()` to read the current state tree inside the callback.
*
* You may call `dispatch()` from a change listener, with the following
* caveats:
*
* 1. The subscriptions are snapshotted just before every `dispatch()` call.
* If you subscribe or unsubscribe while the listeners are being invoked, this
* will not have any effect on the `dispatch()` that is currently in progress.
* However, the next `dispatch()` call, whether nested or not, will use a more
* recent snapshot of the subscription list.
*
* 2. The listener should not expect to see all state changes, as the state
* might have been updated multiple times during a nested `dispatch()` before
* the listener is called. It is, however, guaranteed that all subscribers
* registered before the `dispatch()` started will be called with the latest
* state by the time it exits.
*
* @param {Function} listener A callback to be invoked on every dispatch.
* @returns {Function} A function to remove this change listener.
*/
function subscribe(listener) {
if (typeof listener !== 'function') {
throw new Error('Expected listener to be a function.');
}
var isSubscribed = true;
ensureCanMutateNextListeners();
nextListeners.push(listener);
return function unsubscribe() {
if (!isSubscribed) {
return;
}
isSubscribed = false;
ensureCanMutateNextListeners();
var index = nextListeners.indexOf(listener);
nextListeners.splice(index, 1);
};
}
/**
* Dispatches an action. It is the only way to trigger a state change.
*
* The `reducer` function, used to create the store, will be called with the
* current state tree and the given `action`. Its return value will
* be considered the **next** state of the tree, and the change listeners
* will be notified.
*
* The base implementation only supports plain object actions. If you want to
* dispatch a Promise, an Observable, a thunk, or something else, you need to
* wrap your store creating function into the corresponding middleware. For
* example, see the documentation for the `redux-thunk` package. Even the
* middleware will eventually dispatch plain object actions using this method.
*
* @param {Object} action A plain object representing “what changed”. It is
* a good idea to keep actions serializable so you can record and replay user
* sessions, or use the time travelling `redux-devtools`. An action must have
* a `type` property which may not be `undefined`. It is a good idea to use
* string constants for action types.
*
* @returns {Object} For convenience, the same action object you dispatched.
*
* Note that, if you use a custom middleware, it may wrap `dispatch()` to
* return something else (for example, a Promise you can await).
*/
function dispatch(action) {
if (!isPlainObject(action)) {
throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.');
}
if (typeof action.type === 'undefined') {
throw new Error('Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?');
}
if (isDispatching) {
throw new Error('Reducers may not dispatch actions.');
}
try {
isDispatching = true;
currentState = currentReducer(currentState, action);
} finally {
isDispatching = false;
}
var listeners = currentListeners = nextListeners;
for (var i = 0; i < listeners.length; i++) {
var listener = listeners[i];
listener();
}
return action;
}
/**
* Replaces the reducer currently used by the store to calculate the state.
*
* You might need this if your app implements code splitting and you want to
* load some of the reducers dynamically. You might also need this if you
* implement a hot reloading mechanism for Redux.
*
* @param {Function} nextReducer The reducer for the store to use instead.
* @returns {void}
*/
function replaceReducer(nextReducer) {
if (typeof nextReducer !== 'function') {
throw new Error('Expected the nextReducer to be a function.');
}
currentReducer = nextReducer;
dispatch({ type: ActionTypes.INIT });
}
/**
* Interoperability point for observable/reactive libraries.
* @returns {observable} A minimal observable of state changes.
* For more information, see the observable proposal:
* https://github.com/tc39/proposal-observable
*/
function observable() {
var _ref;
var outerSubscribe = subscribe;
return _ref = {
/**
* The minimal observable subscription method.
* @param {Object} observer Any object that can be used as an observer.
* The observer object should have a `next` method.
* @returns {subscription} An object with an `unsubscribe` method that can
* be used to unsubscribe the observable from the store, and prevent further
* emission of values from the observable.
*/
subscribe: function subscribe(observer) {
if (typeof observer !== 'object') {
throw new TypeError('Expected the observer to be an object.');
}
function observeState() {
if (observer.next) {
observer.next(getState());
}
}
observeState();
var unsubscribe = outerSubscribe(observeState);
return { unsubscribe: unsubscribe };
}
}, _ref[result] = function () {
return this;
}, _ref;
}
// When a store is created, an "INIT" action is dispatched so that every
// reducer returns their initial state. This effectively populates
// the initial state tree.
dispatch({ type: ActionTypes.INIT });
return _ref2 = {
dispatch: dispatch,
subscribe: subscribe,
getState: getState,
replaceReducer: replaceReducer
}, _ref2[result] = observable, _ref2;
}
/**
* Prints a warning in the console if it exists.
*
* @param {String} message The warning message.
* @returns {void}
*/
function warning(message) {
/* eslint-disable no-console */
if (typeof console !== 'undefined' && typeof console.error === 'function') {
console.error(message);
}
/* eslint-enable no-console */
try {
// This error was thrown as a convenience so that if you enable
// "break on all exceptions" in your console,
// it would pause the execution at this line.
throw new Error(message);
/* eslint-disable no-empty */
} catch (e) {}
/* eslint-enable no-empty */
}
/**
* Composes single-argument functions from right to left. The rightmost
* function can take multiple arguments as it provides the signature for
* the resulting composite function.
*
* @param {...Function} funcs The functions to compose.
* @returns {Function} A function obtained by composing the argument functions
* from right to left. For example, compose(f, g, h) is identical to doing
* (...args) => f(g(h(...args))).
*/
/*
* This is a dummy function to check if the function name has been altered by minification.
* If the function has been minified and NODE_ENV !== 'production', warn the user.
*/
function isCrushed() {}
if ("production" !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') {
warning('You are currently using minified code outside of NODE_ENV === \'production\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.');
}
/**
* @class ModuleManager
* @category core
* @param {Object} object handler
* @description Solves modules dependencies
* @memberof module:core
*/
var ModuleManager = function () {
function ModuleManager(object) {
classCallCheck(this, ModuleManager);
this.handler = object;
this.currentModule = null;
this.store = createStore(function () {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [{}, ''];
var action = arguments[1];
state[0][action.key] = action.data;
state[1] = action.key;
return state;
});
this.modules = {};
}
/**
* @method active
* @instance
* @description Sets .currentModule to provided module.
* @param {Object} module the module to make current
* @memberof module:core.ModuleManager
*/
createClass(ModuleManager, [{
key: 'active',
value: function active(module) {
this.currentModule = module;
}
/**
* @method reset
* @instance
* @description Set's .currentModule to null.
* @memberof module:core.ModuleManager
*/
}, {
key: 'reset',
value: function reset() {
this.currentModule = null;
}
/**
* @method define
* @instance
* @description Define the module in manager
* @param name The module name
* @memberof module:core.ModuleManager
*/
}, {
key: 'define',
value: function define(name) {
this.modules[name] = this.currentModule;
}
/**
* @method use
* @instance
* @description Get the defined module from manager
* @param name The module name
* @memberof module:core.ModuleManager
*/
}, {
key: 'use',
value: function use(name) {
return this.modules[name];
}
/**
* @method set
* @instance
* @description An alias for .add() <br/><br/>
* Use this method if you know that you will overwrite existing dependency.<br/>
* Use it in your app, but not in module that you provide to other people.
* @param {String} key the key of the dependency
* @param {Object} data the value of the dependency
* @memberof module:core.ModuleManager
*/
}, {
key: 'set',
value: function set$$1(key, data) {
this.store.dispatch({
type: 'ADD',
key: key,
data: data
});
}
/**
* @method get
* @instance
* @description Returns dependency in store object, by key.
* @param {String} key the key of the dependency
* @memberof module:core.ModuleManager
* @return {Object|Module}
* @throws {DependencyError} if dependency is not in the store
* @example <caption>Get the 'hello' dependency</caption>
* manager.get('hello'); // -> {world: true}
*/
}, {
key: 'get',
value: function get$$1(key) {
if (!this.store.getState()[0][key]) {
throw new DependencyError('ModuleManager', 'Module requires \'' + key + '\' dependency', this.currentModule);
}
return this.store.getState()[0][key];
}
/**
* @method has
* @instance
* @description Returns whether manager has a dependency with the given key
* @param {String} key the key of the dependency
* @memberof module:core.ModuleManager
* @return {Boolean} Promise that is resolved when all promises completed.
* @example <caption>Check whether the store has the 'hello' dependency</caption>
* manager.has('hello'); // -> true
*/
}, {
key: 'has',
value: function has(key) {
return Boolean(this.store.getState()[0][key]);
}
/**
* @method update
* @instance
* @description Updates deps
* @param {Object} [depsMap={}]
* @memberof module:core.ModuleManager
*/
}, {
key: 'update',
value: function update() {
var _this = this;
var depsMap = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
this.store.subscribe(function () {
var _store$getState = _this.store.getState(),
_store$getState2 = slicedToArray(_store$getState, 2),
data = _store$getState2[0],
changedKey = _store$getState2[1];
var callback = depsMap[changedKey];
if (callback) callback(data[changedKey]);
});
}
/**
* @method add
* @alias module:core.ModuleManager#set
* @memberof module:core.ModuleManager
*/
}, {
key: 'add',
value: function add() {
console.warn('.add() method is deprecated. Use .set() instead');
return this.set.apply(this, arguments);
}
/**
* @method require
* @instance
* @description Require module
* @param {String} name Defined name
* @param {Function} moduleExecutor Function that returns applied module
* @memberof module:core.ModuleManager
*/
}, {
key: 'require',
value: function require(name, moduleExecutor) {
if (this.use(name) === undefined) this.handler.applyModule(moduleExecutor());
}
}]);
return ModuleManager;
}();
var _class;
var _temp;
/**
* @class Component
* @category core
* @param {Object} [params] - The parameters object.
* @param {Object} [instructions] - The instructions object.
* @extends ModuleSystem
* @memberof module:core
*/
var Component = (_temp = _class = function (_ModuleSystem) {
inherits(Component, _ModuleSystem);
// For keeping children components;
// Collection of promises;
/**
* Collection of `modules`.
* @member {Array} module:core.Component#modules
* @public
*/
/**
* Static instructions
* @member {Object} module:core.Component#instructions
* @static
* @default {}
*/
function Component() {
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var defaults$$1 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Component.defaults;
var instructions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Component.instructions;
classCallCheck(this, Component);
// Apply polyfilled parameters to .params;
var _this = possibleConstructorReturn(this, (Component.__proto__ || Object.getPrototypeOf(Component)).call(this));
_this._wait = [];
_this.modules = [];
_this.children = [];
_this.params = extend(transformData(params, instructions), defaults$$1);
if (_this.params.manager) _this.manager = new ModuleManager(_this);
_this.modules = _this.params.modules;
_this.integrateModules();
return _this;
}
/**
* @method wait
* @instance
* @description Wait for a promise.
* @param {Promise} [promise] - The promise that should be added to a queue.
* @return {Promise} Promise that is resolved when all promises completed.
* @memberof module:core.Component
*/
// Collection of modules;
/**
* Collection of `child` Components.
* @member {Array} module:core.Component#children
* @public
*/
/**
* Array of promises that should be resolved before Component is ready.
* @member {Array} module:core.Component#_wait
* @private
*/
/**
* Default values for parameters
* @member {Object} module:core.Component#defaults
* @static
* @default {
* modules: [],
* manager: true
* }
*/
createClass(Component, [{
key: 'wait',
value: function wait(promise) {
if (promise) this._wait.push(promise);
return Promise.all(this._wait);
}
/**
* @method defer
* @instance
* @description Execute `func` (Callback) when Component is ready.
* @param {Function} func - Callback.
* @memberof module:core.Component
*/
}, {
key: 'defer',
value: function defer(func) {
var _this2 = this;
if (this.isDeffered) this.wait().then(function () {
return func(_this2);
});else func(this);
}
// PARAMETERS
/**
* @method updateParams
* @instance
* @description Updates parameters of the Component.
* @return {Object} Params of this Component
* @memberof module:core.Component
*/
}, {
key: 'updateParams',
value: function updateParams() {
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
this.params = extend(params, this.params);
return this.params;
}
// COPYING & CLONING
/**
* @method clone
* @instance
* @description Clone this component
* @return {object} a cloned component with all its source component' params copied.
* @memberof module:core.Component
*/
}, {
key: 'clone',
value: function clone() {
return new this.constructor(this.params).copy(this);
}
/**
* @method copy
* @instance
* @description Copy source native and integrate `modules` to it.
* @param {Component} source - Source component that is used for `copy()` action.
* @param {Function} [customize] - Callback executed before modules integration process.
* @return {this} Component
* @memberof module:core.Component
*/
}, {
key: 'copy',
value: function copy(source, customize) {
this.params = _extends({}, source.params);
if (source.native) this.native = source.native.clone(source.params);
if (customize) customize();
this.integrateModules(source);
return this;
}
/**
* @method add
* @instance
* @description Add a child `Component`.
* @param {Component} object - Component that should be added as a `child`.
* @return {Promise} Resolved when action is done.
* @memberof module:core.Component
*/
}, {
key: 'add',
value: function add(object) {
var _this3 = this;
object.parent = this;
return new Promise(function (resolve, reject) {
_this3.defer(function () {
object.defer(function () {
var native = object.native;
if (!native) reject();
var addPromise = _this3.applyBridge({ onAdd: object }).onAdd;
var resolver = function resolver() {
_this3.native.add(native);
_this3.children.push(object);
resolve(object);
};
if (addPromise instanceof Promise) addPromise.then(resolver);else resolver();
});
});
});
}
/**
* @method remove
* @instance
* @description Remove a child `Component`.
* @param {Component} object - Component that should be a **child** of this Component.
* @memberof module:core.Component
*/
}, {
key: 'remove',
value: function remove(object) {
object.parent = null;
this.native.remove(object.native);
}
/**
* @method addTo
* @instance
* @description Adds `this` Component to specified `App`/`Component`.
* @param {Component} object - Component that will be a parent of `this`.
* @memberof module:core.Component
*/
}, {
key: 'addTo',
value: function addTo(object) {
return object.add(this);
}
}, {
key: 'get',
value: function get$$1(key) {
return this.manager.get(key);
}
}, {
key: 'use',
value: function use(key) {
return this.manager.use(key);
}
/**
* Returns whether the object is `async` (`wait` promises are more than `0`).
* @member {Boolean} module:core.Component#isDeffered
*/
}, {
key: 'isDeffered',
get: function get$$1() {
return this._wait.length > 0;
}
/**
* Returns the `ModuleManager` used for this component.
* @member {ModuleManager} module:core.Component#manager
* @throws {ManagerError}
*/
}, {
key: 'manager',
get: function get$$1() {
if (this._manager) return this._manager;
throw new ManagerError('Component', 'ModuleManager is not used in this component. \'manager\' parameter should be set as \'true\'', this);
},
set: function set$$1(manager) {
this._manager = manager;
}
/**
* Returns the `native` object used for this component.
* @member {Object} module:core.Component#native
*/
}, {
key: 'native',
get: function get$$1() {
return this._native;
},
set: function set$$1(mesh) {
this._native = mesh;
this._native.component = this;
return this._native;
}
}]);
return Component;
}(ModuleSystem), _class.defaults = {
modules: null,
manager: true
}, _class.instructions = {}, _temp);
function attributes() {
for (var _len = arguments.length, mappers = Array(_len), _key = 0; _key < _len; _key++) {
mappers[_key] = arguments[_key];
}
return function (target) {
for (var i = 0; i < mappers.length; i++) {
var mapper = mappers[i];
for (var k = 0; k < mapper.map.length; k++) {
var attribute = mapper.map[k];
Object.defineProperty(target.prototype, attribute, {
get: mapper.getter(attribute),
set: mapper.setter(attribute),
configurable: mapper.configurable,
enumerable: mapper.enumerable
});
}
}
};
}
function copy() {
for (var _len2 = arguments.length, map = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
map[_key2] = arguments[_key2];
}
return {
map: map,
getter: function getter(name) {
return function () {
return this.native[name];
};
},
setter: function setter(name) {
return function (value) {
this.native[name].copy(value);
};
},
configurable: true,
enumerable: true
};
}
function mirror() {
for (var _len3 = arguments.length, map = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
map[_key3] = arguments[_key3];
}
return {
map: map,
getter: function getter(name) {
return function () {
return this.native[name];
};
},
setter: function setter(name) {
return function (value) {
this.native[name] = value;
};
},
configurable: true,
enumerable: true
};
}
var _dec;
var _class$1;
var _class2;
var _temp$1;
/**
* @class MeshComponent
* @category core
* @param {Object} [params] - The parameters object.
* @param {Object} [instructions] - The instructions object.
* @extends module:core.Component
* @memberof module:core
*/
var MeshComponent = (_dec = attributes(copy('position', 'rotation', 'quaternion', 'scale'), mirror('material', 'geometry')), _dec(_class$1 = (_temp$1 = _class2 = function (_Component) {
inherits(MeshComponent, _Component);
createClass(MeshComponent, null, [{
key: 'custom',
// CUSTOM GEOMETRY HANDLING
/**
* Default values for parameters
* @member {Object} module:core.MeshComponent#defaults
* @static
* @default
* {
* build: true,
* geometry: {},
* material: false,
*
* shadow: {
* cast: true,
* receive: true
* },
*
* position: {x: 0, y: 0, z: 0},
* rotation: {x: 0, y: 0, z: 0},
* scale: {x: 1, y: 1, z: 1}
* }
*/
value: function custom(geom) {
var constructor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Mesh;
return function (_MeshComponent) {
inherits(_class3, _MeshComponent);
function _class3() {
classCallCheck(this, _class3);
return possibleConstructorReturn(this, (_class3.__proto__ || Object.getPrototypeOf(_class3)).apply(this, arguments));
}
createClass(_class3, [{
key: 'build',
value: function build() {
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.params;
var _applyBridge = this.applyBridge({
geometry: geom,
material: params.material
}),
geometry = _applyBridge.geometry,
material = _applyBridge.material;
return this.applyBridge({ mesh: new constr