import { Component, Properties } from '@hatiolab/things-scene'
import ControlBase, { DIRECTION, INOUT, NODE, PIPELINE } from './base/control-base'
const NATURE = {
mutable: false,
resizable: true,
rotatable: false,
properties: [
{
type: 'select',
name: 'messageType',
label: 'message-type',
property: {
options: [
{
display: '',
value: ''
},
{
display: 'invalid',
value: 'invalid'
},
{
display: 'guaranteed',
value: 'guaranteed'
},
{
display: 'dead-letter',
value: 'dead-letter'
}
]
}
}
],
help: '/eipatterns/messaging-channel/messaging-channel'
}
export default class MessagingChannel extends ControlBase {
private imageElement?: HTMLImageElement
static get nature() {
return NATURE
}
get nodes(): NODE[] {
return [
{
name: 'In',
description: 'Message inlet',
inout: INOUT.IN,
type: PIPELINE.MESSAGE,
direction: DIRECTION.WEST,
multiplicity: 1
},
{
name: 'Out',
description: 'Message outlet',
inout: INOUT.OUT,
type: PIPELINE.MESSAGE,
direction: DIRECTION.EAST
}
]
}
render(ctx: CanvasRenderingContext2D) {
const { left, top, width, height } = this.bounds
const rx = Math.abs(height / 12)
const ry = Math.abs(height / 8)
const startAngle = (Math.PI * 3) / 2
const endAngle = Math.PI / 2
const sy = (height * 3) / 8
const cy = height / 2
const ey = (height * 5) / 8
const isize = (height * 3) / 8
ctx.translate(left, top)
ctx.beginPath()
ctx.ellipse(width - rx, cy, rx, ry, 0, startAngle, startAngle - Math.PI * 2, true)
ctx.lineTo(rx, sy)
ctx.ellipse(rx, cy, rx, ry, 0, startAngle, endAngle, true)
ctx.lineTo(width - rx, ey)
this.drawFill(ctx)
this.drawStroke(ctx)
ctx.beginPath()
const image = this.getImageElement()
if (image) {
this.drawImage(ctx, image, width / 2 - isize / 2, height - isize, isize, isize)
}
ctx.translate(-left, -top)
}
onchange(after: Properties, before: Properties) {
if ('messageType' in after || 'strokeStyle' in after) {
delete this.imageElement
}
}
getImageElement(): HTMLImageElement | undefined {
if (!this.imageElement) {
const { messageType, strokeStyle } = this.state
if (!messageType) {
return
}
const src = IMAGES[messageType]
if (!src) {
return
}
this.imageElement = new Image()
this.imageElement.src =
'data:image/svg+xml;charset=UTF-8;base64,' + btoa(src.replace(/{{strokeColor}}/g, strokeStyle))
}
return this.imageElement
}
}
Component.register('messaging-channel', MessagingChannel)
const IMAGES = {
'dead-letter': `
`,
invalid: `
`,
guaranteed: `
`
}