Home Manual Reference Source Test

lib/helpers.js

import Ticker from "@statetree/ticker";

/**
 * Based on return value of predicate, this function decides whether to execute the method immediately or in frame cycle
 *
 * @param {function} predicate
 * @param {function} apiFunc
 * @param {function} callback Api func execution may be sync or Async, if its sync we cant return notifier as user can register doneCallback after API invocation
 * @param {function} errorCallback
 * @return {void}
 */
export function executeInSyncOrAsync(predicate, apiFunc, callback, errorCallback){
	// Important to create inside closure to execute in Ticker
	const _executeLater = ()=>{
		if(predicate()){ // execute API calls Only after all user added functions are executed
			const returnValue = apiFunc();
			callback && callback(returnValue);
		} else {
			let ticker = new Ticker(_executeLater, null, 2);
			errorCallback && ticker.onError(errorCallback);
			ticker.executeInCycle()
		}
	};
	_executeLater();
};

export function executeAsync(predicate, apiFunc){
	// Important to create inside closure to execute in Ticker
	const _executeLater = ()=>{
		let ticker;
		if(predicate()){ // execute API calls Only after all user added functions are executed
			ticker = new Ticker(apiFunc, null, 2);
		} else {
			ticker = new Ticker(_executeLater, null, 2);
		}
		return ticker.executeInCycle()
	};
	return _executeLater();
};

/**
 * Executes all the stored functions , if callLater enabled, executes them in frame cycle
 *
 * @param {array} entries of  which contains the function and its context.
 * @param {boolean} callLater indicates execution needs to happen in frame cycle
 * @return {number} return count of entries that are added to execute in loop later
 */
export function executeEntries(entries, callLater = false){
	const disposedEntriesIndex = [];
	let delayedEntriesCount = 0;
	entries.forEach(function(entry, index){
		if (entry.func) {
			callLater && (delayedEntriesCount = delayedEntriesCount + 1);
			entry.func.apply(entry.context || entry.func['this']);
		} else {
			disposedEntriesIndex.push(index);
		}
	});
	clearDisposedEntries(disposedEntriesIndex,entries);
	return delayedEntriesCount;
}

function clearDisposedEntries(indices, entries){
	if(typeof indices === 'number'){
		entries.splice(indices,1);
	} else {
		indices.forEach(function(entryIndex){
			entries.splice(entryIndex,1);
		})
	}
}

function getEntry(list, index, isTicker){
	if(isTicker){
		const tickerEntry =  list[index];
		return tickerEntry.context;
	} else {
		return list[index];
	}
}


export function disposeAndRemoveEntry(func, context, list , isTicker){
	for(let i = 0; i < list.length; i++){
		let entry = getEntry(list,i,isTicker);
		if(entry && entry.func && entry.func === func && entry.context === context){
			list[i].dispose();
			clearDisposedEntries(i, list);
			return;
		}
	}
};