2023-06-02 12:00:21 +02:00
|
|
|
/*
|
2023-11-08 18:28:18 +01:00
|
|
|
* (promise-able) EVENTS (optionally continue after listeners are finished using .then)
|
2023-06-02 12:00:21 +02:00
|
|
|
*
|
|
|
|
|
* example:
|
|
|
|
|
*
|
|
|
|
|
* xrf.addEventListener('foo',(e) => {
|
|
|
|
|
* // let promise = e.promise()
|
|
|
|
|
* console.log("navigating to: "+e.detail.destination.url)
|
|
|
|
|
* // promise.resolve()
|
|
|
|
|
* // promise.reject("not going to happen")
|
|
|
|
|
* })
|
|
|
|
|
*
|
|
|
|
|
* xrf.emit('foo',123)
|
|
|
|
|
* xrf.emit('foo',123).then(...).catch(...).finally(...)
|
|
|
|
|
*/
|
|
|
|
|
|
2024-01-24 18:11:37 +00:00
|
|
|
xrf.addEventListener = function(eventName, callback, opts) {
|
2023-10-26 18:45:13 +02:00
|
|
|
if( !this._listeners ) this._listeners = []
|
2024-01-24 18:11:37 +00:00
|
|
|
callback.opts = opts || {weight: this._listeners.length}
|
2023-10-26 18:45:13 +02:00
|
|
|
if (!this._listeners[eventName]) {
|
|
|
|
|
// create a new array for this event name if it doesn't exist yet
|
|
|
|
|
this._listeners[eventName] = [];
|
2023-10-26 13:19:03 +02:00
|
|
|
}
|
2023-10-26 18:45:13 +02:00
|
|
|
// add the callback to the listeners array for this event name
|
|
|
|
|
this._listeners[eventName].push(callback);
|
2024-01-24 18:11:37 +00:00
|
|
|
// sort
|
|
|
|
|
this._listeners[eventName] = this._listeners[eventName].sort( (a,b) => a.opts.weight > b.opts.weight )
|
2023-10-26 18:45:13 +02:00
|
|
|
return () => {
|
|
|
|
|
this._listeners[eventName] = this._listeners[eventName].filter( (c) => c != callback )
|
|
|
|
|
}
|
|
|
|
|
};
|
2023-10-26 13:19:03 +02:00
|
|
|
|
2023-06-02 12:00:21 +02:00
|
|
|
xrf.emit = function(eventName, data){
|
2023-06-22 08:49:24 +02:00
|
|
|
if( typeof data != 'object' ) throw 'emit() requires passing objects'
|
2024-01-31 17:58:24 +00:00
|
|
|
if( xrf.debug && ( !eventName.match(/^render/) || xrf.debug == eventName ) ){
|
2023-11-08 18:28:18 +01:00
|
|
|
let label = String(`xrf.emit('${eventName}')`).padEnd(35," ");
|
|
|
|
|
label += data.mesh && data.mesh.name ? '#'+data.mesh.name : ''
|
|
|
|
|
console.groupCollapsed(label)
|
|
|
|
|
console.info(data)
|
|
|
|
|
console.groupEnd(label)
|
|
|
|
|
if( xrf.debug > 1 ) debugger
|
|
|
|
|
}
|
2023-06-02 12:00:21 +02:00
|
|
|
return xrf.emit.promise(eventName,data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xrf.emit.normal = function(eventName, data) {
|
|
|
|
|
if( !xrf._listeners ) xrf._listeners = []
|
|
|
|
|
var callbacks = xrf._listeners[eventName]
|
|
|
|
|
if (callbacks) {
|
|
|
|
|
for (var i = 0; i < callbacks.length; i++) {
|
2024-01-03 14:23:34 +00:00
|
|
|
try{
|
2023-06-02 12:00:21 +02:00
|
|
|
callbacks[i](data);
|
2024-01-03 14:23:34 +00:00
|
|
|
}catch(e){ console.error(e) }
|
2023-06-02 12:00:21 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
xrf.emit.promise = function(e, opts){
|
|
|
|
|
return new Promise( (resolve, reject) => {
|
|
|
|
|
opts.promise = () => {
|
2023-11-08 18:28:18 +01:00
|
|
|
opts.promises = opts.promises || []
|
|
|
|
|
opts.promises.push(0)
|
|
|
|
|
return {
|
|
|
|
|
resolve: ((index) => () => {
|
|
|
|
|
opts.promises[index] = 1
|
|
|
|
|
let succesful = opts.promises.reduce( (a,b) => a+b )
|
|
|
|
|
if( succesful == opts.promises.length ) resolve(opts)
|
|
|
|
|
})(opts.promises.length-1),
|
|
|
|
|
reject: console.error
|
|
|
|
|
}
|
2023-06-02 12:00:21 +02:00
|
|
|
}
|
|
|
|
|
xrf.emit.normal(e, opts)
|
2023-11-08 18:28:18 +01:00
|
|
|
if( !opts.promises ) resolve(opts)
|
2023-09-15 19:42:37 +02:00
|
|
|
delete opts.promise
|
2023-06-02 12:00:21 +02:00
|
|
|
})
|
|
|
|
|
}
|
2023-11-30 13:25:27 +01:00
|
|
|
|
|
|
|
|
xrf.addEventListener('reset', () => {
|
|
|
|
|
// *TODO* do this nicely
|
|
|
|
|
// xrf._listeners['renderPost'] = []
|
|
|
|
|
// xrf._listeners['render'] = []
|
|
|
|
|
})
|