-
Notifications
You must be signed in to change notification settings - Fork 828
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* initial draft from Shaofeng * add copyright headers * rewrites to readme with images * renaming job variables for clarity * added UI animation for reference * small code and comment cleanups * added correct button icons * added correct button icons * update image * Fixes and cleanup work to readme * update manifests * created cleaner localhost references (#97) Co-authored-by: David Chesnut <[email protected]> Co-authored-by: Maarten van Stam <[email protected]>
- Loading branch information
1 parent
b627c2a
commit bd5be63
Showing
16 changed files
with
1,065 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
self.addEventListener('message', | ||
function(event) { | ||
var job = event.data; | ||
if (typeof(job) == "string") { | ||
job = JSON.parse(job); | ||
} | ||
|
||
var jobId = job.jobId; | ||
try { | ||
var result = invokeFunction(job.name, job.parameters); | ||
// check whether the result is a promise. | ||
if (typeof(result) == "function" || typeof(result) == "object" && typeof(result.then) == "function") { | ||
result.then(function(realResult) { | ||
postMessage( | ||
{ | ||
jobId: jobId, | ||
result: realResult | ||
} | ||
); | ||
}) | ||
.catch(function(ex) { | ||
postMessage( | ||
{ | ||
jobId: jobId, | ||
error: true | ||
} | ||
) | ||
}); | ||
} | ||
else { | ||
postMessage({ | ||
jobId: jobId, | ||
result: result | ||
}); | ||
} | ||
} | ||
catch(ex) { | ||
postMessage({ | ||
jobId: jobId, | ||
error: true | ||
}); | ||
} | ||
} | ||
); | ||
|
||
function invokeFunction(name, parameters) { | ||
if (name == "TEST") { | ||
return test.apply(null, parameters); | ||
} | ||
else if (name == "TEST_PROMISE") { | ||
return test_promise.apply(null, parameters); | ||
} | ||
else if (name == "TEST_ERROR") { | ||
return test_error.apply(null, parameters); | ||
} | ||
else if (name == "TEST_ERROR_PROMISE") { | ||
return test_error_promise.apply(null, parameters); | ||
} | ||
else { | ||
throw new Error("not supported"); | ||
} | ||
} | ||
|
||
function test(n) { | ||
var ret = 0; | ||
for (var i = 0; i < n; i++) { | ||
ret += Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(50)))))))))); | ||
for (var l = 0; l < n; l++) { | ||
ret -= Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(50)))))))))); | ||
} | ||
} | ||
return ret; | ||
} | ||
|
||
|
||
function test_promise(n) { | ||
return new Promise(function(resolve, reject) { | ||
setTimeout(function() { | ||
resolve(test(n)); | ||
}, 1000); | ||
}); | ||
} | ||
|
||
function test_error(n) { | ||
throw new Error(); | ||
} | ||
|
||
function test_error_promise(n) { | ||
return Promise.reject(new Error()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
var SampleNamespace = {}; | ||
|
||
(function(SampleNamespace) { | ||
// The max number of web workers to be created | ||
var g_maxWebWorkers = 4; | ||
|
||
// The array of web workers | ||
var g_webworkers = []; | ||
|
||
// Next job id | ||
var g_nextJobId = 0; | ||
|
||
// The promise info for the job. It stores the {resolve: resolve, reject: reject} information for the job. | ||
var g_jobIdToPromiseInfoMap = {}; | ||
|
||
function getOrCreateWebWorker(jobId) { | ||
var index = jobId % g_maxWebWorkers; | ||
if (g_webworkers[index]) { | ||
return g_webworkers[index]; | ||
} | ||
|
||
// create a new web worker | ||
var webWorker = new Worker("functions-worker.js"); | ||
webWorker.addEventListener('message', function(event) { | ||
var jobResult = event.data; | ||
if (typeof(jobResult) == "string") { | ||
jobResult = JSON.parse(jobResult); | ||
} | ||
|
||
if (typeof(jobResult.jobId) == "number") { | ||
var jobId = jobResult.jobId; | ||
// get the promise info associated with the job id | ||
var promiseInfo = g_jobIdToPromiseInfoMap[jobId]; | ||
if (promiseInfo) { | ||
if (jobResult.error) { | ||
// The web worker returned an error | ||
promiseInfo.reject(new Error()); | ||
} | ||
else { | ||
// The web worker returned a result | ||
promiseInfo.resolve(jobResult.result); | ||
} | ||
delete g_jobIdToPromiseInfoMap[jobId]; | ||
} | ||
} | ||
}); | ||
|
||
g_webworkers[index] = webWorker; | ||
return webWorker; | ||
} | ||
|
||
// Post a job to the web worker to do the calculation | ||
function dispatchCalculationJob(functionName, parameters) { | ||
var jobId = g_nextJobId++; | ||
return new Promise(function(resolve, reject) { | ||
// store the promise information. | ||
g_jobIdToPromiseInfoMap[jobId] = {resolve: resolve, reject: reject}; | ||
var worker = getOrCreateWebWorker(jobId); | ||
worker.postMessage({ | ||
jobId: jobId, | ||
name: functionName, | ||
parameters: parameters | ||
}); | ||
}); | ||
} | ||
|
||
SampleNamespace.dispatchCalculationJob = dispatchCalculationJob; | ||
})(SampleNamespace); | ||
|
||
|
||
CustomFunctions.associate("TEST", function(n) { | ||
return SampleNamespace.dispatchCalculationJob("TEST", [n]); | ||
}); | ||
|
||
CustomFunctions.associate("TEST_PROMISE", function(n) { | ||
return SampleNamespace.dispatchCalculationJob("TEST_PROMISE", [n]); | ||
}); | ||
|
||
CustomFunctions.associate("TEST_ERROR", function(n) { | ||
return SampleNamespace.dispatchCalculationJob("TEST_ERROR", [n]); | ||
}); | ||
|
||
CustomFunctions.associate("TEST_ERROR_PROMISE", function(n) { | ||
return SampleNamespace.dispatchCalculationJob("TEST_ERROR_PROMISE", [n]); | ||
}); | ||
|
||
|
||
// This function will show what happens when calculations are run on the main UI thread. | ||
// The task pane will be blocked until this method completes. | ||
CustomFunctions.associate("TEST_UI_THREAD", function(n) { | ||
var ret = 0; | ||
for (var i = 0; i < n; i++) { | ||
ret += Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(50)))))))))); | ||
for (var l = 0; l < n; l++) { | ||
ret -= Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(Math.tan(Math.atan(50)))))))))); | ||
} | ||
} | ||
return ret; | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
{ | ||
"functions": [ | ||
{ | ||
"id": "TEST_UI_THREAD", | ||
"parameters": [ | ||
{ | ||
"name": "n" | ||
} | ||
] | ||
}, | ||
{ | ||
"id": "TEST", | ||
"parameters": [ | ||
{ | ||
"name": "n" | ||
} | ||
] | ||
}, | ||
{ | ||
"id": "TEST_PROMISE", | ||
"parameters": [ | ||
{ | ||
"name": "n" | ||
} | ||
] | ||
}, | ||
{ | ||
"id": "TEST_ERROR", | ||
"parameters": [ | ||
{ | ||
"name": "n" | ||
} | ||
] | ||
}, | ||
{ | ||
"id": "TEST_ERROR_PROMISE", | ||
"parameters": [ | ||
{ | ||
"name": "n" | ||
} | ||
] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
<!-- Copyright (c) Microsoft Corporation. | ||
Licensed under the MIT License. --> | ||
|
||
<html> | ||
<head> | ||
<title>Custom functions using WebWorker</title> | ||
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script> | ||
<script src="functions.js" type="text/javascript"></script> | ||
<script type="text/javascript"> | ||
|
||
var ballX = 100; | ||
var ballY = 10; | ||
var ballDirection = 'downRight'; | ||
|
||
Office.onReady(function() { | ||
animate(); | ||
console.log("Office.onReady"); | ||
}); | ||
|
||
function animate() { | ||
|
||
setInterval(drawBall, 10); | ||
} | ||
|
||
var drawBall = () => { | ||
var canvas = document.getElementById('mycanvas'); | ||
|
||
if (canvas.getContext) { | ||
var ctx = canvas.getContext('2d'); | ||
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); | ||
moveBall(ctx.canvas.width,ctx.canvas.height); | ||
var radius=20; | ||
|
||
ctx.beginPath(); | ||
ctx.arc(ballX,ballY,radius,0,2*Math.PI,false); | ||
ctx.fillStyle = 'green'; | ||
ctx.fill(); | ||
ctx.lineWidth = 4; | ||
ctx.strokeStyle = '#003300'; | ||
ctx.stroke(); | ||
} | ||
} | ||
|
||
var moveBall = (width,height) => { | ||
//check for ball collision with context boundaries | ||
|
||
if (ballX <= 0) { | ||
if (ballDirection === 'upLeft') { | ||
ballDirection = 'upRight'; | ||
} else { | ||
ballDirection = "downRight"; | ||
} | ||
} | ||
if (ballY <=0) { | ||
if (ballDirection === 'upLeft') { | ||
ballDirection = 'downLeft'; | ||
|
||
} else { | ||
ballDirection = "downRight"; | ||
} | ||
} | ||
if (ballX >= width) { | ||
if (ballDirection ==='upRight'){ | ||
ballDirection = 'upLeft'; | ||
|
||
} else { | ||
ballDirection = 'downLeft'; | ||
} | ||
} | ||
if (ballY >= height) { | ||
if (ballDirection ==='downRight'){ | ||
ballDirection = 'upRight'; | ||
} else { | ||
ballDirection = 'upLeft'; | ||
} | ||
} | ||
switch (ballDirection) { | ||
case 'upRight': { | ||
ballX++; | ||
ballY--; | ||
break; | ||
} | ||
case 'upLeft': { | ||
ballX--; | ||
ballY--; | ||
break; | ||
} | ||
case 'downRight': { | ||
ballX++; | ||
ballY++; | ||
break; | ||
} | ||
case 'downLeft': { | ||
ballX--; | ||
ballY++; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
</script> | ||
</head> | ||
<body> | ||
<canvas id = "mycanvas" width = "200" height = "200"></canvas> | ||
</body> | ||
</html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+85.4 KB
Excel-custom-functions/web-worker/images/office-add-ins-my-account.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.