topical media & game development
mobile-query-three-js-tquery.core.js / js
@fileOverview This file is the core of tQuery library.
Create a tQuery element
@class root class
parameter: {} object
parameter: {THREE.Object3D} rootnode
returns: {tQuery.*} the tQuery object created
var tQuery = function(object, root)
{
// support for tQuery(geometry, material)
if( arguments.length === 2 &&
(arguments[0] instanceof THREE.Geometry
|| arguments[0] instanceof THREE.BufferGeometry
|| arguments[0] instanceof tQuery.Geometry)
&&
(arguments[1] instanceof THREE.Material || arguments[1] instanceof tQuery.Material)
){
var tGeometry = arguments[0] instanceof tQuery.Geometry ? arguments[0].get(0) : arguments[0];
var tMaterial = arguments[1] instanceof tQuery.Material ? arguments[1].get(0) : arguments[1];
var tMesh = new THREE.Mesh(tGeometry, tMaterial);
return tQuery( tMesh );
}
// TODO make tthat cleaner
// - there is a list of functions registered by each plugins
// - handle() object instanceof THREE.Mesh
// - create() return new tQuery(object)
// - this list is processed in order here
// if the object is an array, compare only the first element
// - up to the subconstructor to check if the whole array has proper type
var instance = Array.isArray(object) ? object[0] : object;
if( instance instanceof THREE.Mesh && tQuery.Mesh){
return new tQuery.Mesh(object);
}else if( instance instanceof THREE.DirectionalLight && tQuery.DirectionalLight){
return new tQuery.DirectionalLight(object);
}else if( instance instanceof THREE.AmbientLight && tQuery.AmbientLight){
return new tQuery.AmbientLight(object);
}else if( instance instanceof THREE.Light && tQuery.Light){
return new tQuery.Light(object);
}else if( instance instanceof THREE.Object3D && tQuery.Object3D){
return new tQuery.Object3D(object);
}else if( instance instanceof THREE.Geometry && tQuery.Geometry){
return new tQuery.Geometry(object);
}else if( instance instanceof THREE.Material && tQuery.Material){
return new tQuery.Material(object);
}else if( typeof instance === "string" && tQuery.Object3D){
return new tQuery.Object3D(object, root);
}else{
console.assert(false, "unsupported type")
}
return undefined;
};
The version of tQuery
tQuery.VERSION = "r56.0";
////////////////////////////////////////////////////////////////////////////
// //
////////////////////////////////////////////////////////////////////////////
generic getter/setter
parameter: {Object} object the object in which store the data
parameter: {String} key the key/name of the data to get/set
parameter: {*} value the value to set (optional)
parameter: {Boolean} mustNotExist if true, ensure that the key doesnt already exist, optional default to false
returns: {*} return the value stored in this object for this key
tQuery.data = function(object, key, value, mustNotExist)
{
// sanity check
console.assert( object, 'invalid parameters' );
console.assert( typeof key === 'string', 'invalid parameters');
// init _tqData
object['_tqData'] = object['_tqData'] || {};
// honor mustNotExist
if( mustNotExist ){
console.assert(object['_tqData'][key] === undefined, "This key already exists "+key);
}
// set the value if any
if( value ){
object['_tqData'][key] = value;
}
// return the value
return object['_tqData'][key];
};
test if the data exist
parameter: {Object} object the object which may or may not contain the data
parameter: {string} key the key of the data
returns: {Boolean} true if the data exist, false otherwise
tQuery.hasData = function(object, key){
// if there is no data at all, return false
if( object['_tqData'] === undefined ) return false;
// if this data doesnt exist, return false
if( object['_tqData'][key] === undefined ) return false;
// if all previous test passed, return true
return true;
}
Same as jQuery.removeData()
parameter: {Boolean} mustExist if true, ensure the key does exist, default to false
tQuery.removeData = function(object, key, mustExist)
{
// handle the 'key as Array' case
if( key instanceof Array ){
key.forEach(function(key){
tQuery.removeData(object, key);
})
return;
}
// sanity check
console.assert( typeof key === "string");
// honor mustNotExist
if( mustExist ){
console.assert(object['_tqData'][key] !== undefined, "This key doesnt already exists "+key);
}
// do delete the key
delete object['_tqData'][key];
// TOTO remove object [tqData] if empty now
}
////////////////////////////////////////////////////////////////////////////
// //
////////////////////////////////////////////////////////////////////////////
loop over a Array.
parameter: {Array} arr the array to traverse.
parameter: {Function} callback the function to notify. function(element){ }.
loop interrupted if it returns false
returns: {Boolean} return true if completed, false if interrupted
tQuery.each = function(arr, callback){
for(var i = 0; i < arr.length; i++){
var keepLooping = callback(arr[i])
if( keepLooping === false ) return false;
}
return true;
};
precise version of Date.now() -
It provide submillisecond precision based on window.performance.now() when
available, fall back on Date.now()
see http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision
tQuery.now = (function(){
var p = window.performance || {};
if( p.now ) return function(){ return p.timing.navigationStart + p.now(); };
else if( p.mozNow ) return function(){ return p.timing.navigationStart + p.mozNow(); };
else if( p.webkitNow ) return function(){ return p.timing.navigationStart + p.webkitNow() };
else if( p.mskitNow ) return function(){ return p.timing.navigationStart + p.msNow() };
else if( p.okitNow ) return function(){ return p.timing.navigationStart + p.oNow() };
else return function(){ return Date.now; };
})();
Make a child Class inherit from the parent class.
parameter: {Object} childClass the child class which gonna inherit
parameter: {Object} parentClass the class which gonna be inherited
tQuery.inherit = function(childClass, parentClass){
// trick to avoid calling parentClass constructor
var tempFn = function() {};
tempFn.prototype = parentClass.prototype;
childClass.prototype = new tempFn();
childClass.parent = parentClass.prototype;
childClass.prototype.constructor= childClass;
};
extend function. mainly aimed at handling default values - jme: im not sure at all it is the proper one.
http://jsapi.info/_/extend
similar to jquery one but much smaller
tQuery.extend = function(obj, base, deep){
// handle parameter polymorphism
deep = deep !== undefined ? deep : true;
var extendFn = deep ? deepExtend : shallowExtend;
var result = {};
base && extendFn(result, base);
obj && extendFn(result, obj);
return result;
function shallowExtend(dst, src){
Object.keys(src).forEach(function(key){
dst[key] = src[key];
})
};
// from http://andrewdupont.net/2009/08/28/deep-extending-objects-in-javascript/
function deepExtend(dst, src){
for (var property in src) {
if (src[property] && src[property].constructor && src[property].constructor === Object) {
dst[property] = dst[property] || {};
arguments.callee(dst[property], src[property]);
} else {
dst[property] = src[property];
}
}
return dst;
};
};
////////////////////////////////////////////////////////////////////////////
// //
////////////////////////////////////////////////////////////////////////////
Make an object pluginable
parameter: {Object} object the object on which you mixin function
parameter: {Object} dest the object in which to register the plugin
parameter: {string} suffix the suffix to add to the function name
tQuery._pluginsOn = function(object, dest, fnNameSuffix){
dest = dest || object.prototype || object;
fnNameSuffix = fnNameSuffix || '';
// sanity check
console.assert(object['register'+fnNameSuffix] === undefined);
console.assert(object['unregister'+fnNameSuffix] === undefined);
console.assert(object['registered'+fnNameSuffix] === undefined);
object['register'+fnNameSuffix] = function(name, funct) {
console.assert(dest[name] === undefined, 'Conflict! Already method called: ' + name);
dest[name] = funct;
};
object['unregister'+fnNameSuffix] = function(name){
if( dest.hasOwnProperty(name) === false ){
throw new Error('Plugin not found: ' + name);
}
delete dest[name];
};
object['registered'+fnNameSuffix] = function(name){
return dest.hasOwnProperty(name) === true;
}
};
tQuery.pluginsInstanceOn= function(klass){
tQuery._pluginsOn(klass, undefined, 'Instance');
};
tQuery.pluginsStaticOn = function(klass){
tQuery._pluginsOn(klass, klass, 'Static');
};
// make it pluginable as static
tQuery.pluginsStaticOn(tQuery);
////////////////////////////////////////////////////////////////////////////
// //
////////////////////////////////////////////////////////////////////////////
tQuery.mixinAttributes = function(dstObject, properties){
// mixin the new property
// FIXME the inheritance should work now... not sure
dstObject.prototype._attrProps = tQuery.extend(dstObject.prototype._attrProps, properties);
dstObject.prototype.attr = function(name, args){
// handle parameters
if( name instanceof Object && args === undefined ){
Object.keys(name).forEach(function(key){
this.attr(key, name[key]);
}.bind(this));
}else if( typeof(name) === 'string' ){
console.assert( Object.keys(this._attrProps).indexOf(name) !== -1, 'invalid property name:'+name);
}else console.assert(false, 'invalid parameter');
// handle setter
if( args !== undefined ){
var convertFn = this._attrProps[name];
var value = convertFn.apply(convertFn, args);
this.each(function(element){
element[name] = value;
})
return this;
}
// handle getter
if( this.length === 0 ) return undefined
var element = this.get(0);
return element[name];
};
// add shortcuts
Object.keys(properties).forEach(function(name){
dstObject.prototype[name] = function(/* arguments */){
return this.attr(name, arguments);
};
}.bind(this));
};
////////////////////////////////////////////////////////////////////////////
// put some helpers //
////////////////////////////////////////////////////////////////////////////
Flow control - from github.com/jeromeetienne/gowiththeflow.js
tQuery.Flow = function(){
var self, stack = [], timerId = setTimeout(function(){ timerId = null; self._next(); }, 0);
return self = {
destroy : function(){ timerId && clearTimeout(timerId); },
par : function(callback, isSeq){
if(isSeq || !(stack[stack.length-1] instanceof Array)) stack.push([]);
stack[stack.length-1].push(callback);
return self;
},seq : function(callback){ return self.par(callback, true); },
_next : function(err, result){
var errors = [], results = [], callbacks = stack.shift() || [], nbReturn = callbacks.length, isSeq = nbReturn == 1;
callbacks && callbacks.forEach(function(fct, index){
fct(function(error, result){
errors[index] = error;
results[index] = result;
if(--nbReturn == 0) self._next(isSeq?errors[0]:errors, isSeq?results[0]:results)
}, err, result)
})
}
}
};
microevents.js - github.com/jeromeetienne/microevent.js
tQuery.MicroeventMixin = function(destObj){
var bind = function(event, fct){
if(this._events === undefined) this._events = {};
this._events[event] = this._events[event] || [];
this._events[event].push(fct);
return fct;
};
var unbind = function(event, fct){
if(this._events === undefined) this._events = {};
if( event in this._events === false ) return;
this._events[event].splice(this._events[event].indexOf(fct), 1);
};
var trigger = function(event /* , args... */){
if(this._events === undefined) this._events = {};
if( this._events[event] === undefined ) return;
var tmpArray = this._events[event].slice();
for(var i = 0; i < tmpArray.length; i++){
var result = tmpArray[i].apply(this, Array.prototype.slice.call(arguments, 1))
if( result !== undefined ) return result;
}
return undefined;
};
// backward compatibility
destObj.bind = bind;
destObj.unbind = unbind;
destObj.trigger = trigger;
destObj.addEventListener = function(event, fct){
this.bind(event, fct)
return this; // for chained API
}
destObj.removeEventListener = function(event, fct){
this.unbind(event, fct)
return this; // for chained API
}
destObj.dispatchEvent = function(event /* , args... */){
return this.trigger.apply(this, arguments)
}
};
github.com/jeromeetienne/MicroCache.js
tQuery.MicroCache = function(){
var _values = {};
return {
get : function(key){ return _values[key]; },
contains: function(key){ return key in _values; },
remove : function(key){ delete _values[key]; },
set : function(key, value){ _values[key] = value;},
values : function(){ return _values; },
getSet : function(key, value){
if( !this.contains(key) ){
this.set(key, typeof value == 'function' ? value() : value )
}
return this.get(key);
}
}
}
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.