Skip to content

Commit

Permalink
add global execution queue
Browse files Browse the repository at this point in the history
  • Loading branch information
kbrsh committed Apr 18, 2019
1 parent b3caaf6 commit e980c3a
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 136 deletions.
108 changes: 41 additions & 67 deletions packages/moon/dist/moon.js
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@
/**
* Global data
*/
var data;
var data = {};
/**
* Global views
*/
Expand All @@ -561,14 +561,6 @@
*/

var components = {};
/**
* Set data to a new object.
* @param {Object} dataNew
*/

function setData(dataNew) {
data = dataNew;
}
/**
* Set old view to a new object.
* @param {Object} viewOld
Expand Down Expand Up @@ -600,10 +592,10 @@

var executeStart;
/**
* Function scheduled to run in next frame
* Execution queue
*/

var executeNextId = null;
var executeQueue = [];
/**
* Types of patches
*/
Expand All @@ -615,33 +607,13 @@
removeElement: 3,
replaceElement: 4
};
/**
* Schedules a function to run in the next frame.
* @param {Function} fn
*/

function executeNext(fn) {
executeNextId = requestAnimationFrame(fn);
}
/**
* Cancels the function scheduled to run in the next frame.
*/


function executeCancel() {
if (executeNextId !== null) {
cancelAnimationFrame(executeNextId);
executeNextId = null;
}
}
/**
* Creates a DOM element from a view node.
*
* @param {Object} node
* @returns {Object} node to be used as an old node
*/


function executeCreate(node) {
var nodeType = node.type;
var nodeName = node.name;
Expand Down Expand Up @@ -737,7 +709,7 @@
} else if (performance.now() - executeStart >= 8) {
// If the current frame doesn't have sufficient time left to keep
// running then continue executing the view in the next frame.
executeNext(function () {
requestAnimationFrame(function () {
executeStart = performance.now();
executeView(nodes, parents, indexes);
});
Expand Down Expand Up @@ -842,7 +814,7 @@
} else if (performance.now() - executeStart >= 8) {
// If the current frame doesn't have sufficient time left to keep
// running then continue diffing in the next frame.
executeNext(function () {
requestAnimationFrame(function () {
executeStart = performance.now();
executeDiff(nodesOld, nodesNew, patches);
});
Expand Down Expand Up @@ -916,7 +888,7 @@

_nodeParent.data.children.pop();

_nodeParent.node.removeChild(patch.nodeOld);
_nodeParent.node.removeChild(patch.nodeOld.node);

break;
}
Expand All @@ -943,8 +915,33 @@
break;
}
}
} // Remove the current execution from the queue.


executeQueue.shift(); // If there is new data in the execution queue, continue to it.

if (executeQueue.length !== 0) {
executeNext();
}
}
/**
* Execute the next update in the execution queue.
*/


function executeNext() {
// Get the next data update.
var dataNew = executeQueue[0]; // Record the current time to reference when running different functions.

executeStart = performance.now(); // Merge new data into current data.

for (var key in dataNew) {
data[key] = dataNew[key];
} // Begin executing the view.


executeView([viewCurrent(data)], [null], [0]);
}
/**
* Executor
*
Expand All @@ -968,41 +965,20 @@
* are all batched together to update the view. Rather than doing it along with
* the diff phase, the patch is done in one frame to prevent an inconsistent
* UI -- similar to screen tearing.
*/


function execute() {
// Cancel any function scheduled to run in the next frame.
executeCancel(); // Record the current time to reference when running different functions.

executeStart = performance.now(); // Begin executing the view.

executeView([viewCurrent(data)], [null], [0]);
}

/**
* Tracks if an execution is queued.
*/

var queued = false;
/**
* Updates the global data and view.
*
* @param {Object} dataNew
*/

function set(dataNew) {
for (var key in dataNew) {
data[key] = dataNew[key];
}

if (queued === false) {
queued = true;
setTimeout(function () {
execute();
queued = false;
}, 0);
function execute(dataNew) {
// Push the new data to the execution queue.
executeQueue.push(dataNew); // Execute the next function in the queue if none are scheduled yet.

if (executeQueue.length === 1) {
executeNext();
}
}

/**
* Moon
*
Expand Down Expand Up @@ -1030,7 +1006,6 @@
* @param {Object|string} options.view
*/


function Moon(options) {
// Handle the optional `name` parameter.
var name = defaultValue(options.name, "Root");
Expand Down Expand Up @@ -1066,16 +1041,15 @@
node: root
});
setViewCurrent(view);
setData(options);
execute();
execute(options);
}
}
Moon.lex = lex;
Moon.parse = parse;
Moon.generate = generate;
Moon.compile = compile;
Moon.components = components;
Moon.set = set;
Moon.set = execute;

return Moon;
}));
2 changes: 1 addition & 1 deletion packages/moon/dist/moon.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 43 additions & 31 deletions packages/moon/src/executor/executor.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { types } from "../util/util";
let executeStart;

/**
* Function scheduled to run in next frame
* Execution queue
*/
let executeNextId = null;
let executeQueue = [];

/**
* Types of patches
Expand All @@ -22,24 +22,6 @@ const patchTypes = {
replaceElement: 4
};

/**
* Schedules a function to run in the next frame.
* @param {Function} fn
*/
function executeNext(fn) {
executeNextId = requestAnimationFrame(fn);
}

/**
* Cancels the function scheduled to run in the next frame.
*/
function executeCancel() {
if (executeNextId !== null) {
cancelAnimationFrame(executeNextId);
executeNextId = null;
}
}

/**
* Creates a DOM element from a view node.
*
Expand Down Expand Up @@ -147,8 +129,9 @@ function executeView(nodes, parents, indexes) {
} else if (performance.now() - executeStart >= 8) {
// If the current frame doesn't have sufficient time left to keep
// running then continue executing the view in the next frame.
executeNext(() => {
requestAnimationFrame(() => {
executeStart = performance.now();

executeView(nodes, parents, indexes);
});

Expand Down Expand Up @@ -255,8 +238,9 @@ function executeDiff(nodesOld, nodesNew, patches) {
} else if (performance.now() - executeStart >= 8) {
// If the current frame doesn't have sufficient time left to keep
// running then continue diffing in the next frame.
executeNext(() => {
requestAnimationFrame(() => {
executeStart = performance.now();

executeDiff(nodesOld, nodesNew, patches);
});

Expand Down Expand Up @@ -330,7 +314,7 @@ function executePatch(patches) {
// efficient than removing at a specific index, especially because
// they are equivalent in this case.
nodeParent.data.children.pop();
nodeParent.node.removeChild(patch.nodeOld);
nodeParent.node.removeChild(patch.nodeOld.node);

break;
}
Expand All @@ -357,6 +341,33 @@ function executePatch(patches) {
}
}
}

// Remove the current execution from the queue.
executeQueue.shift();

// If there is new data in the execution queue, continue to it.
if (executeQueue.length !== 0) {
executeNext();
}
}

/**
* Execute the next update in the execution queue.
*/
function executeNext() {
// Get the next data update.
const dataNew = executeQueue[0];

// Record the current time to reference when running different functions.
executeStart = performance.now();

// Merge new data into current data.
for (let key in dataNew) {
data[key] = dataNew[key];
}

// Begin executing the view.
executeView([viewCurrent(data)], [null], [0]);
}

/**
Expand All @@ -382,14 +393,15 @@ function executePatch(patches) {
* are all batched together to update the view. Rather than doing it along with
* the diff phase, the patch is done in one frame to prevent an inconsistent
* UI -- similar to screen tearing.
*
* @param {Object} dataNew
*/
export function execute() {
// Cancel any function scheduled to run in the next frame.
executeCancel();

// Record the current time to reference when running different functions.
executeStart = performance.now();
export function execute(dataNew) {
// Push the new data to the execution queue.
executeQueue.push(dataNew);

// Begin executing the view.
executeView([viewCurrent(data)], [null], [0]);
// Execute the next function in the queue if none are scheduled yet.
if (executeQueue.length === 1) {
executeNext();
}
}
31 changes: 3 additions & 28 deletions packages/moon/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,9 @@ import { parse } from "./compiler/parser/parser";
import { generate } from "./compiler/generator/generator";
import { compile } from "./compiler/compiler";
import { execute } from "./executor/executor";
import { components, data, setData, setViewCurrent, setViewOld } from "./util/globals";
import { components, setViewCurrent, setViewOld } from "./util/globals";
import { defaultObject, defaultValue, error, types } from "./util/util";

/**
* Tracks if an execution is queued.
*/
let queued = false;

/**
* Updates the global data and view.
* @param {Object} dataNew
*/
function set(dataNew) {
for (let key in dataNew) {
data[key] = dataNew[key];
}

if (queued === false) {
queued = true;

setTimeout(() => {
execute();
queued = false;
}, 0);
}
}

/**
* Moon
*
Expand Down Expand Up @@ -94,8 +70,7 @@ export default function Moon(options) {
node: root
});
setViewCurrent(view);
setData(options);
execute();
execute(options);
}
}

Expand All @@ -104,4 +79,4 @@ Moon.parse = parse;
Moon.generate = generate;
Moon.compile = compile;
Moon.components = components;
Moon.set = set;
Moon.set = execute;
Loading

0 comments on commit e980c3a

Please sign in to comment.