experiments(dui3): extra cleanup and comments around

This commit is contained in:
Dimitrie Stefanescu
2023-07-10 20:12:35 +01:00
parent 5f3b7a16f2
commit c452458812
4 changed files with 60 additions and 38 deletions
+35 -19
View File
@@ -1,12 +1,15 @@
// TODO
import { rejects } from 'assert'
import { uniqueId } from 'lodash-es'
import { resolve } from 'path'
declare let sketchup: {
exec: (data: Record<string, unknown>) => void
}
/**
* This class operates in different way than the others, because calls into Sketchup are one way only.
* E.g., we cannot return values from internal calls to it (e.g., const test = sketchup.rubyCall() does not work ).
* Values are passed back
*/
export class SketchupBridge {
private requests = {} as Record<
string,
@@ -19,38 +22,51 @@ export class SketchupBridge {
private bindingsName: string
private TIMEOUT_MS = 2000 // 2s
public isInitalized: Promise<void>
private isInitializedResolved!: () => unknown
private resolveIsInitializedPromise!: () => unknown
constructor(bindingsName: string) {
// window.sketchup
this.bindingsName = bindingsName || 'default_bindings'
// Initialization continues in the receiveCommandsAndInitializeBridge function,
// where we expect sketchup to return to us the command names.
sketchup.exec({ name: 'get_commands' })
// Initialization continues in the receiveCommandsAndInitializeBridge function
this.isInitalized = new Promise((resolve, reject) => {
// TODO
this.isInitializedResolved = resolve
this.resolveIsInitializedPromise = resolve
setTimeout(
() =>
reject(
`Failed to get command names from Sketchup; timed out after ${this.TIMEOUT_MS}ms.`
),
this.TIMEOUT_MS
)
})
}
// executeScript(...) from skp
/**
* Will be called by `executeScript('bindings.receiveCommandsAndInitializeBridge()')` from sketchup. This is where the hoisting happens.
* NOTE: Oguhzan, we can defintively have commandNames be a string, and not a string[]
* And do JSON.parse() here to get them out properly.
* @param commandNames
*/
private receiveCommandsAndInitializeBridge(commandNames: string[]) {
const hoistTarget = this as unknown as Record<string, unknown>
for (const commandName of commandNames) {
hoistTarget[commandName] = (...args: unknown[]) =>
this.runMethod(commandName, args)
}
// this.isInitalized = true
this.isInitializedResolved()
this.resolveIsInitializedPromise()
}
/**
* Internal calls to Sketchup.
* @param methodName
* @param args
*/
private async runMethod(methodName: string, args: unknown[]): Promise<unknown> {
const requestId = uniqueId(this.bindingsName)
// The single exec way
sketchup.exec({ name: methodName, requestId, args })
return new Promise((resolve, reject) => {
@@ -59,22 +75,22 @@ export class SketchupBridge {
reject,
rejectTimerId: window.setTimeout(() => {
reject(
'Sketchup response timed out - did not receive anything back in good time.'
`Sketchup response timed out - did not receive anything back in good time (${this.TIMEOUT_MS}ms).`
)
// TODO: clear request from requests object
delete this.requests[requestId]
}, this.TIMEOUT_MS)
}
})
}
private receiveResponse(requestId: string, data: string) {
// TODO
if (!this.requests[requestId]) return // throw new error?
if (!this.requests[requestId])
throw new Error(
`Sketchup Bridge found no request to resolve with the id of ${requestId}. Something is weird!`
)
const request = this.requests[requestId]
try {
// TODO: resolve also if data is null, it means it's a
// 'void' function call (does not return anything)
const parsedData = JSON.parse(data) as Record<string, unknown>
const parsedData = JSON.parse(data) as Record<string, unknown> // TODO: check if data is undefined
request.resolve(parsedData)
} catch (e) {
request.reject(e as Error)
+15 -18
View File
@@ -30,7 +30,9 @@ export default defineNuxtPlugin(async () => {
console.info('Bound WebUIBinding object for CefSharp.')
bindings = new CefSharpBridge(WebUIBinding) as unknown as IWebUiBinding
} catch (e) {
console.warn('Failed to bind CefSharp.')
console.warn(
'Failed to bind CefSharp. This can be totally normal if the host is different.'
)
console.warn(e)
}
@@ -38,24 +40,26 @@ export default defineNuxtPlugin(async () => {
if (!chrome.webview) throw new Error('No global Webview2 object found.')
bindings = new WebView2Bridge('WebUIBinding') as unknown as IWebUiBinding
console.info('Bound WebUIBinding object for Webview2.')
const res = await bindings.sayHi('Test')
console.log(res)
} catch (e) {
console.warn('Failed to bind Webview2.')
console.warn(
'Failed to bind Webview2. This can be totally normal if the host is different.'
)
console.warn(e)
}
try {
if (!sketchup) throw new Error('No global sketchup object found.')
console.info('Found Sketchup. Hi SketchUp! We have yet... a lot of work to do :) ')
// TODO
const skpBindings = new SketchupBridge('default_bindings')
await skpBindings.isInitalized // resolve({...})
const skpBindings = new SketchupBridge('default_bindings')
// Note, because of the way Sketchup bindings work, we need to wait here
// for them to be fully initialized.
await skpBindings.isInitalized
bindings = skpBindings as unknown as IWebUiBinding
} catch (e) {
console.warn('Failed to bind sketchup.')
console.warn(
'Failed to bind sketchup. This can be totally normal if the host is different.'
)
console.warn(e)
}
@@ -64,17 +68,10 @@ export default defineNuxtPlugin(async () => {
bindings = MockedBindings
}
// We need the bindings object in global scope to allow
// host applications to send messages back to it.
;(globalThis as Record<string, unknown>).bindings = bindings
// bindings.on('test', (args) => {
// console.log(args)
// })
// bindings.on('documentChanged', (args) => {
// // do somethings
// args.x
// })
return {
provide: {
bindings
+2 -1
View File
@@ -1,5 +1,6 @@
import { createNanoEvents, Emitter } from 'nanoevents'
/* eslint-disable @typescript-eslint/require-await */
import { createNanoEvents } from 'nanoevents'
export type Account = {
id: string
isDefault: boolean
+8
View File
@@ -10933,6 +10933,7 @@ __metadata:
graphql: ^16.6.0
graphql-tag: ^2.12.6
lodash-es: ^4.17.21
nanoevents: ^8.0.0
nuxt: ^3.5.0
portal-vue: ^3.0.0
postcss: ^8.4.18
@@ -32762,6 +32763,13 @@ __metadata:
languageName: node
linkType: hard
"nanoevents@npm:^8.0.0":
version: 8.0.0
resolution: "nanoevents@npm:8.0.0"
checksum: 46806fb1bca823de1dac0ec38352c9ebd25dd9f2186eada6357f2941983203c1c77fc383e460852a139b4ced569af2a2777f82cb574f705fd6f8402497f4bfc2
languageName: node
linkType: hard
"nanoid@npm:3.3.3":
version: 3.3.3
resolution: "nanoid@npm:3.3.3"