mirror of https://github.com/espruino/BangleApps
Allow optionally drawing using timeouts
parent
36e2a64cda
commit
627c58e8cd
|
@ -9,7 +9,9 @@ var endPerfLog = () => {};
|
|||
var printPerfLog = () => print("Deactivated");
|
||||
var resetPerfLog = () => {performanceLog = {};};
|
||||
|
||||
var graphics = Graphics.createArrayBuffer(176,176,16,{msb:true});
|
||||
var plane0 = g;
|
||||
var plane1;
|
||||
|
||||
if (false){
|
||||
startPerfLog = function(name){
|
||||
var time = getTime();
|
||||
|
@ -100,7 +102,7 @@ function isChangedMultistate(element){
|
|||
return element.lastDrawnValue != getMultistate(element.Value);
|
||||
}
|
||||
|
||||
function drawNumber(resources, element, offset){
|
||||
function drawNumber(graphics, resources, element, offset){
|
||||
startPerfLog("drawNumber");
|
||||
var number = getValue(element.Value);
|
||||
var spacing = element.Spacing ? element.Spacing : 0;
|
||||
|
@ -187,9 +189,9 @@ function drawNumber(resources, element, offset){
|
|||
if (isNegative && minusImage){
|
||||
//print("Draw minus at", currentX);
|
||||
if (imageIndexMinus){
|
||||
drawElement(resources, {X:currentX,Y:firstDigitY}, numberOffset, element, "" + (0 + imageIndexMinus));
|
||||
drawElement(graphics, resources, {X:currentX,Y:firstDigitY}, numberOffset, element, "" + (0 + imageIndexMinus));
|
||||
} else {
|
||||
drawElement(resources, {X:currentX,Y:firstDigitY}, numberOffset, element, "minus");
|
||||
drawElement(graphics, resources, {X:currentX,Y:firstDigitY}, numberOffset, element, "minus");
|
||||
}
|
||||
currentX += minusImage.width + spacing;
|
||||
}
|
||||
|
@ -202,14 +204,14 @@ function drawNumber(resources, element, offset){
|
|||
currentDigit = 0;
|
||||
}
|
||||
//print("Digit " + currentDigit + " " + currentX);
|
||||
drawElement(resources, {X:currentX,Y:firstDigitY}, numberOffset, element, currentDigit + imageIndex);
|
||||
drawElement(graphics, resources, {X:currentX,Y:firstDigitY}, numberOffset, element, currentDigit + imageIndex);
|
||||
currentX += firstImage.width + spacing;
|
||||
}
|
||||
if (imageIndexUnit){
|
||||
//print("Draw unit at", currentX);
|
||||
drawElement(resources, {X:currentX,Y:firstDigitY}, numberOffset, element, "" + (0 + imageIndexUnit));
|
||||
drawElement(graphics, resources, {X:currentX,Y:firstDigitY}, numberOffset, element, "" + (0 + imageIndexUnit));
|
||||
} else if (element.Unit){
|
||||
drawElement(resources, {X:currentX,Y:firstDigitY}, numberOffset, element, getMultistate(element.Unit,"unknown"));
|
||||
drawElement(graphics, resources, {X:currentX,Y:firstDigitY}, numberOffset, element, getMultistate(element.Unit,"unknown"));
|
||||
}
|
||||
element.lastDrawnValue = number;
|
||||
|
||||
|
@ -221,7 +223,7 @@ function setColors(properties){
|
|||
if (properties.bg) graphics.setBgColor(properties.bg);
|
||||
}
|
||||
|
||||
function drawElement(resources, pos, offset, element, lastElem){
|
||||
function drawElement(graphics, resources, pos, offset, element, lastElem){
|
||||
startPerfLog("drawElement");
|
||||
var cacheKey = "_"+(lastElem?lastElem:"nole");
|
||||
if (!element.cachedImage) element.cachedImage={};
|
||||
|
@ -287,7 +289,7 @@ function getMultistate(name, defaultValue){
|
|||
return undefined;
|
||||
}
|
||||
|
||||
function drawScale(resources, scale, offset){
|
||||
function drawScale(graphics, resources, scale, offset){
|
||||
startPerfLog("drawScale");
|
||||
//print("drawScale", scale, offset);
|
||||
var segments = scale.Segments;
|
||||
|
@ -302,35 +304,35 @@ function drawScale(resources, scale, offset){
|
|||
var segmentsToDraw = Math.ceil(value * segments.length);
|
||||
|
||||
for (var i = 0; i < segmentsToDraw; i++){
|
||||
drawElement(resources, segments[i], scaleOffset, scale, imageIndex + i);
|
||||
drawElement(graphics, resources, segments[i], scaleOffset, scale, imageIndex + i);
|
||||
}
|
||||
scale.lastDrawnValue = segmentsToDraw;
|
||||
|
||||
endPerfLog("drawScale");
|
||||
}
|
||||
|
||||
function drawDigit(resources, element, offset, digit){
|
||||
drawElement(resources, element, offset, element, digit);
|
||||
function drawDigit(graphics, resources, element, offset, digit){
|
||||
drawElement(graphics, resources, element, offset, element, digit);
|
||||
}
|
||||
|
||||
function drawImage(resources, image, offset, name){
|
||||
function drawImage(graphics, resources, image, offset, name){
|
||||
startPerfLog("drawImage");
|
||||
var imageOffset = updateColors(image, offset);
|
||||
//print("drawImage", image, offset, name);
|
||||
if (image.Value && image.Steps){
|
||||
var steps = Math.floor(scaledown(image.Value, image.MinValue, image.MaxValue) * (image.Steps - 1));
|
||||
//print("Step", steps, "of", image.Steps);
|
||||
drawElement(resources, image, imageOffset, image, "" + steps);
|
||||
drawElement(graphics, resources, image, imageOffset, image, "" + steps);
|
||||
} else if (image.ImageIndex !== undefined) {
|
||||
drawElement(resources, image, imageOffset, image, image.ImageIndex);
|
||||
drawElement(graphics, resources, image, imageOffset, image, image.ImageIndex);
|
||||
} else {
|
||||
drawElement(resources, image, imageOffset, image, name ? "" + name: undefined);
|
||||
drawElement(graphics, resources, image, imageOffset, image, name ? "" + name: undefined);
|
||||
}
|
||||
|
||||
endPerfLog("drawImage");
|
||||
}
|
||||
|
||||
function drawCodedImage(resources, image, offset){
|
||||
function drawCodedImage(graphics, resources, image, offset){
|
||||
startPerfLog("drawCodedImage");
|
||||
var code = getValue(image.Value);
|
||||
//print("drawCodedImage", image, offset, code);
|
||||
|
@ -348,10 +350,10 @@ function drawCodedImage(resources, image, offset){
|
|||
}
|
||||
if (code / factor > 1){
|
||||
//print("found match");
|
||||
drawImage(resources, image, offset, currentCode);
|
||||
drawImage(graphics, resources, image, offset, currentCode);
|
||||
} else {
|
||||
//print("fallback");
|
||||
drawImage(resources, image, offset, "fallback");
|
||||
drawImage(graphics, resources, image, offset, "fallback");
|
||||
}
|
||||
}
|
||||
image.lastDrawnValue = code;
|
||||
|
@ -425,7 +427,7 @@ function radians(rotation){
|
|||
return value;
|
||||
}
|
||||
|
||||
function drawPoly(resources, element, offset){
|
||||
function drawPoly(graphics, resources, element, offset){
|
||||
startPerfLog("drawPoly");
|
||||
var vertices = [];
|
||||
var primitiveOffset = offset.clone();
|
||||
|
@ -463,7 +465,7 @@ function drawPoly(resources, element, offset){
|
|||
endPerfLog("drawPoly");
|
||||
}
|
||||
|
||||
function drawRect(resources, element, offset){
|
||||
function drawRect(graphics, resources, element, offset){
|
||||
startPerfLog("drawRect");
|
||||
var vertices = [];
|
||||
var primitiveOffset = offset.clone();
|
||||
|
@ -535,12 +537,12 @@ multistates.WeatherTemperatureNegative = () => { return getWeatherTemperature().
|
|||
multistates.WeatherTemperatureUnit = () => { return getWeatherTemperature().unit; };
|
||||
multistates.StepsGoal = () => { return (numbers.Steps() >= stepsgoal) ? "on": "off"; };
|
||||
|
||||
function drawMultiState(resources, element, offset){
|
||||
function drawMultiState(graphics, resources, element, offset){
|
||||
startPerfLog("drawMultiState");
|
||||
//print("drawMultiState", element, offset);
|
||||
var value = multistates[element.Value]();
|
||||
//print("drawImage from drawMultiState", element, offset, value);
|
||||
drawImage(resources, element, offset, value);
|
||||
drawImage(graphics, resources, element, offset, value);
|
||||
element.lastDrawnValue = value;
|
||||
endPerfLog("drawMultiState");
|
||||
}
|
||||
|
@ -568,24 +570,13 @@ function initialDraw(resources, face){
|
|||
requestedDraws = 0;
|
||||
//print(new Date().toISOString(), "Drawing start");
|
||||
startPerfLog("initialDraw");
|
||||
//var start = Date.now();
|
||||
//start = Date.now();
|
||||
drawingTime = 0;
|
||||
//print("Precompiled");
|
||||
var promise = Promise.resolve();
|
||||
if (clearOnRedraw){
|
||||
promise = promise.then(()=>{
|
||||
var currentDrawingTime = Date.now();
|
||||
startPerfLog("initialDraw_g.clear");
|
||||
graphics.clear(true);
|
||||
endPerfLog("initialDraw_g.clear");
|
||||
drawingTime += Date.now() - currentDrawingTime;
|
||||
});
|
||||
}
|
||||
promise = promise.then(()=>precompiledJs(watchfaceResources, watchface));
|
||||
var promise = precompiledJs(watchfaceResources, watchface);
|
||||
|
||||
promise.then(()=>{
|
||||
var currentDrawingTime = Date.now();
|
||||
g.drawImage({width: graphics.getWidth(), height: graphics.getHeight(), bpp: graphics.getBPP(), buffer: graphics.buffer});
|
||||
lastDrawTime = Date.now() - start;
|
||||
drawingTime += Date.now() - currentDrawingTime;
|
||||
//print(new Date().toISOString(), "Drawing done in", lastDrawTime.toFixed(0), "active:", drawingTime.toFixed(0));
|
||||
|
@ -593,6 +584,8 @@ function initialDraw(resources, face){
|
|||
firstDraw=false;
|
||||
requestRefresh = false;
|
||||
endPerfLog("initialDraw");
|
||||
}).catch((e)=>{
|
||||
print("Error during drawing", e);
|
||||
});
|
||||
|
||||
if (requestedDraws > 0){
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
|
||||
<p>
|
||||
Options:</br>
|
||||
<input type="checkbox" id="promisewrap" name="mode" checked/>
|
||||
<label for="promisewrap">Wrap draw calls in timeouts (Slower, more RAM use, better interactivity)</label></br>
|
||||
<input type="checkbox" id="timeoutwrap" name="mode" checked/>
|
||||
<label for="timeoutwrap">Wrap draw calls in timeouts (Slower, more RAM use, better interactivity)</label></br>
|
||||
</p>
|
||||
|
||||
<p>Select watchface folder:</br><input type="file" id="fileLoader" name="files[]" multiple directory="" webkitdirectory="" moxdirectory="" /></p>
|
||||
|
@ -561,26 +561,50 @@
|
|||
return result;
|
||||
}
|
||||
|
||||
function convertToCode(elements, properties, wrapInPromises){
|
||||
function convertToCode(elements, properties, wrapInTimeouts){
|
||||
var code = "(function (watchfaceResources, watchface) {\n";
|
||||
if (!wrapInPromises){
|
||||
if (!wrapInTimeouts){
|
||||
code += "var currentDrawTime=Date.now();\n";
|
||||
}
|
||||
code += "var layerchanged;\n";
|
||||
code += "var layerchanged;\n";
|
||||
code += "var promise = Promise.resolve();\n";
|
||||
|
||||
//get mapped by layer
|
||||
var layers = {};
|
||||
var counter = 0;
|
||||
var planes = 0;
|
||||
for (var i = 0; i< elements.length; i++){
|
||||
var c = elements[i].value;
|
||||
console.log("Check element", c);
|
||||
var name = c.Layer;
|
||||
if (c.type == "Standalone") name = "standalone" + counter++;
|
||||
if (c.Plane) planes = Math.max(c.Plane, planes);
|
||||
if (!layers[name]) layers[name] = [];
|
||||
layers[name].push({index: i, element: c});
|
||||
}
|
||||
|
||||
console.log("Found planes", planes)
|
||||
|
||||
if (wrapInTimeouts && planes == 0) planes = 1;
|
||||
|
||||
code += "plane0 = g;\n";
|
||||
|
||||
if (planes > 0){
|
||||
for (var i = 1; i <= planes; i++){
|
||||
code += "if (!plane" + i + ") plane" + i + " = Graphics.createArrayBuffer(g.getWidth(),g.getHeight(),16,{msb:true});\n";
|
||||
}
|
||||
}
|
||||
|
||||
code += `
|
||||
if (clearOnRedraw){
|
||||
var currentDrawingTime = Date.now();
|
||||
startPerfLog("initialDraw_g.clear");
|
||||
g.clear(true);
|
||||
endPerfLog("initialDraw_g.clear");
|
||||
drawingTime += Date.now() - currentDrawingTime;
|
||||
}
|
||||
`
|
||||
|
||||
console.log("Got layers", layers);
|
||||
|
||||
for (var layername in layers){
|
||||
|
@ -589,7 +613,7 @@
|
|||
console.log("Layer elements", layername, layerElements);
|
||||
//code for whole layer
|
||||
|
||||
if (wrapInPromises){
|
||||
if (wrapInTimeouts){
|
||||
code += "promise = promise.then(()=>delay(0)).then(()=>{\n";
|
||||
code += "var currentDrawTime=Date.now();\n";
|
||||
}
|
||||
|
@ -616,7 +640,7 @@
|
|||
}
|
||||
|
||||
code += checkcode;
|
||||
|
||||
|
||||
//code for elements
|
||||
for (var i = 0; i< layerElements.length; i++){
|
||||
var elementIndex = layerElements[i].index;
|
||||
|
@ -639,27 +663,38 @@
|
|||
condition += "firstDraw";
|
||||
}
|
||||
|
||||
var planeName = "plane" + (typeof c.value.Plane == "number" ? c.value.Plane : planes) ;
|
||||
|
||||
var colorsetting = "";
|
||||
if (c.value.ForegroundColor) colorsetting += "g.setColor(\"" + c.value.ForegroundColor + "\");\n";
|
||||
else colorsetting += "g.setColor(g.theme.fg);\n";
|
||||
if (c.value.BackgroundColor) colorsetting += "g.setBgColor(\"" + c.value.BackgroundColor + "\");\n";
|
||||
else colorsetting += "g.setBgColor(g.theme.bg);\n";
|
||||
if (c.value.ForegroundColor) colorsetting += planeName + ".setColor(\"" + c.value.ForegroundColor + "\");\n";
|
||||
else colorsetting += planeName + ".setColor(g.theme.fg);\n";
|
||||
if (c.value.BackgroundColor) colorsetting += planeName + ".setBgColor(\"" + c.value.BackgroundColor + "\");\n";
|
||||
else colorsetting += planeName + ".setBgColor(g.theme.bg);\n";
|
||||
|
||||
code += (condition.length > 0 ? "if (" + condition + "){\n" : "");
|
||||
code += "" + colorsetting;
|
||||
code += "draw" + c.type + "(watchfaceResources, watchface.Collapsed[" + elementIndex + "].value, {X:0,Y:0});\n";
|
||||
code += "draw" + c.type + "(" + planeName + ", watchfaceResources, watchface.Collapsed[" + elementIndex + "].value, {X:0,Y:0});\n";
|
||||
|
||||
code += (condition.length > 0 ? "}\n" : "");
|
||||
}
|
||||
|
||||
if (wrapInPromises){
|
||||
if (wrapInTimeouts){
|
||||
code += "drawingTime += Date.now() - currentDrawTime;\n";
|
||||
code += "});\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!wrapInPromises){
|
||||
if (planes > 0){
|
||||
code += "promise = promise.then(()=>{\n";
|
||||
code += "var currentDrawTime=Date.now();\n";
|
||||
|
||||
for (var i = 1; i <= planes; i++){
|
||||
//code += "g.drawImage(plane" + i + ".asImage());";
|
||||
code += "g.drawImage(g.drawImage({width: plane" + i + ".getWidth(), height: plane" + i + ".getHeight(), bpp: plane" + i + ".getBPP(), buffer: plane" + i + ".buffer}));";
|
||||
}
|
||||
|
||||
code += "drawingTime += Date.now() - currentDrawTime;\n";
|
||||
code += "});\n";
|
||||
}
|
||||
|
||||
code += "return promise;})";
|
||||
|
@ -674,7 +709,7 @@
|
|||
var properties = faceJson.Properties;
|
||||
faceJson = { Properties: properties, Collapsed: collapseTree(faceJson,{X:0,Y:0})};
|
||||
console.log("After collapsing", faceJson);
|
||||
precompiledJs = convertToCode(faceJson.Collapsed, properties, document.getElementById('promisewrap').checked);
|
||||
precompiledJs = convertToCode(faceJson.Collapsed, properties, document.getElementById('timeoutwrap').checked);
|
||||
console.log("After precompiling", precompiledJs);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue