@fmsim/machine 1.0.47 → 1.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agv-line.js +1 -1
- package/dist/agv-line.js.map +1 -1
- package/dist/carrier.js +7 -7
- package/dist/carrier.js.map +1 -1
- package/dist/conveyor.js +1 -1
- package/dist/conveyor.js.map +1 -1
- package/dist/editors/ox-input-nodes.js +120 -56
- package/dist/editors/ox-input-nodes.js.map +1 -1
- package/dist/editors/ox-property-editor-nodes.js +1 -11
- package/dist/editors/ox-property-editor-nodes.js.map +1 -1
- package/dist/features/mcs-status-mixin.js +3 -0
- package/dist/features/mcs-status-mixin.js.map +1 -1
- package/dist/mcs-vehicle.js +39 -0
- package/dist/mcs-vehicle.js.map +1 -1
- package/dist/node.js +22 -1
- package/dist/node.js.map +1 -1
- package/dist/oht-line.js +1 -1
- package/dist/oht-line.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/agv-line.ts +1 -1
- package/src/carrier.ts +7 -7
- package/src/conveyor.ts +1 -1
- package/src/editors/ox-input-nodes.ts +129 -62
- package/src/editors/ox-property-editor-nodes.ts +2 -15
- package/src/features/mcs-status-mixin.ts +4 -0
- package/src/mcs-vehicle.ts +51 -0
- package/src/node.ts +25 -1
- package/src/oht-line.ts +1 -1
- package/translations/en.json +3 -1
- package/translations/ja.json +3 -1
- package/translations/ko.json +3 -1
- package/translations/ms.json +3 -1
- package/translations/zh.json +3 -1
package/src/agv-line.ts
CHANGED
package/src/carrier.ts
CHANGED
|
@@ -59,7 +59,7 @@ export default class Carrier extends MCSStatusMixin(ParentObjectMixin(Shape)) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
if (decorator || border || arrow) {
|
|
62
|
-
this.trigger('
|
|
62
|
+
this.trigger('deco-off')
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -76,18 +76,18 @@ export default class Carrier extends MCSStatusMixin(ParentObjectMixin(Shape)) {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
if (decorator) {
|
|
79
|
-
this.trigger('
|
|
80
|
-
this.trigger('icon', decorator)
|
|
79
|
+
this.trigger('deco-icon-off')
|
|
80
|
+
this.trigger('deco-icon', decorator)
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
if (border) {
|
|
84
|
-
this.trigger('
|
|
85
|
-
this.trigger('border', border)
|
|
84
|
+
this.trigger('deco-border-off')
|
|
85
|
+
this.trigger('deco-border', border)
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
if (arrow) {
|
|
89
|
-
this.trigger('
|
|
90
|
-
this.trigger('
|
|
89
|
+
this.trigger('deco-arrow-off')
|
|
90
|
+
this.trigger('deco-arrow', arrow)
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
}
|
package/src/conveyor.ts
CHANGED
|
@@ -32,7 +32,7 @@ export default class Conveyor extends MCSTransport {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
containable(component: Component) {
|
|
35
|
-
return ['Shuttle', 'Port'].includes(component.state.type)
|
|
35
|
+
return ['Shuttle', 'Port', 'Node'].includes(component.state.type)
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
renderConveyor(ctx: CanvasRenderingContext2D) {
|
|
@@ -4,101 +4,168 @@
|
|
|
4
4
|
|
|
5
5
|
import '@material/web/icon/icon.js'
|
|
6
6
|
|
|
7
|
-
import { css, html } from 'lit'
|
|
8
|
-
import { customElement, state } from 'lit/decorators.js'
|
|
7
|
+
import { css, html, nothing } from 'lit'
|
|
8
|
+
import { customElement, state, query, queryAll } from 'lit/decorators.js'
|
|
9
9
|
|
|
10
10
|
import { OxFormField } from '@operato/input'
|
|
11
|
-
import { Node } from '../types'
|
|
12
11
|
|
|
13
12
|
@customElement('ox-input-nodes')
|
|
14
13
|
export class OxInputNodes extends OxFormField {
|
|
15
14
|
static styles = [
|
|
16
15
|
css`
|
|
17
16
|
:host {
|
|
18
|
-
display: flex;
|
|
19
|
-
--md-icon-size: 1.4em;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
fieldset {
|
|
23
|
-
flex: 1;
|
|
24
|
-
font-size: 0.8em;
|
|
25
|
-
border: 0;
|
|
26
|
-
border-bottom: 1px solid;
|
|
27
|
-
background-color: var(--md-sys-color-surface-variant);
|
|
28
|
-
padding: var(--spacing-medium);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
ul {
|
|
32
17
|
display: flex;
|
|
33
18
|
flex-direction: column;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
|
|
21
|
+
--md-icon-size: 14px;
|
|
22
|
+
--spacing-large: 16px;
|
|
23
|
+
--spacing-medium: 8px;
|
|
24
|
+
--spacing-small: 4px;
|
|
25
|
+
--spacing-tiny: 2px;
|
|
26
|
+
--padding-default: 4px;
|
|
27
|
+
--button-color: rgba(0, 0, 0, 0.5);
|
|
28
|
+
--button-border: 1px solid rgba(0, 0, 0, 0.15);
|
|
29
|
+
--button-background-color: rgba(0, 0, 0, 0.05);
|
|
30
|
+
--button-background-focus-color: rgba(0, 0, 0, 0.1);
|
|
31
|
+
--button-active-border: 1px solid rgba(0, 0, 0, 0.2);
|
|
38
32
|
}
|
|
39
33
|
|
|
40
|
-
|
|
34
|
+
div {
|
|
41
35
|
display: flex;
|
|
42
|
-
flex-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
flex-flow: row nowrap;
|
|
37
|
+
gap: var(--spacing-medium);
|
|
38
|
+
margin-bottom: var(--spacing-small);
|
|
45
39
|
}
|
|
46
40
|
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
button {
|
|
42
|
+
border: var(--button-border);
|
|
43
|
+
border-radius: var(--border-radius);
|
|
44
|
+
background-color: var(--button-background-color);
|
|
45
|
+
padding: var(--spacing-small) var(--padding-default);
|
|
46
|
+
line-height: 0.8;
|
|
47
|
+
color: var(--button-color);
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
}
|
|
50
|
+
button + button {
|
|
51
|
+
margin-left: -5px;
|
|
52
|
+
}
|
|
53
|
+
button:focus,
|
|
54
|
+
button:hover,
|
|
55
|
+
button:active {
|
|
56
|
+
border: var(--button-active-border);
|
|
57
|
+
background-color: var(--button-background-focus-color);
|
|
58
|
+
color: rgba(0, 0, 0, 0.5);
|
|
49
59
|
}
|
|
50
60
|
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
input {
|
|
62
|
+
flex: 1;
|
|
63
|
+
border: 0;
|
|
64
|
+
border: 1px solid rgba(0, 0, 0, 0.15);
|
|
65
|
+
padding: var(--spacing-tiny);
|
|
66
|
+
font: var(--input-font);
|
|
67
|
+
min-width: 50px;
|
|
53
68
|
}
|
|
54
69
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
70
|
+
input:focus {
|
|
71
|
+
outline: none;
|
|
72
|
+
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
58
73
|
}
|
|
59
74
|
`
|
|
60
75
|
]
|
|
61
76
|
|
|
62
|
-
@state() value:
|
|
77
|
+
@state() value: string[] = []
|
|
78
|
+
|
|
79
|
+
@queryAll('[data-record]') records!: NodeListOf<HTMLElement>
|
|
80
|
+
@query('[data-record-new] [data-id]') addinput!: HTMLInputElement
|
|
81
|
+
|
|
82
|
+
private _changingNow: boolean = false
|
|
83
|
+
|
|
84
|
+
firstUpdated() {
|
|
85
|
+
this.renderRoot.addEventListener('change', this._onChange.bind(this))
|
|
86
|
+
}
|
|
63
87
|
|
|
64
88
|
render() {
|
|
65
|
-
const
|
|
89
|
+
const value = this.value || []
|
|
66
90
|
|
|
67
91
|
return html`
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
92
|
+
${value.map(
|
|
93
|
+
item => html`
|
|
94
|
+
<div data-record>
|
|
95
|
+
<input
|
|
96
|
+
type="text"
|
|
97
|
+
data-id
|
|
98
|
+
.value=${item}
|
|
99
|
+
@keyup=${(e: KeyboardEvent) => e.key === 'Enter' && this._build()}
|
|
100
|
+
/>
|
|
101
|
+
<button
|
|
102
|
+
class="record-action"
|
|
103
|
+
@click=${(e: MouseEvent) => this._delete(e)}
|
|
104
|
+
tabindex="-1"
|
|
105
|
+
?disabled=${this.disabled}
|
|
106
|
+
>
|
|
107
|
+
<md-icon>remove</md-icon>
|
|
108
|
+
</button>
|
|
109
|
+
</div>
|
|
110
|
+
`
|
|
111
|
+
)}
|
|
112
|
+
${this.disabled
|
|
113
|
+
? nothing
|
|
114
|
+
: html`
|
|
115
|
+
<div data-record-new>
|
|
116
|
+
<input type="text" data-id value="" @keyup=${(e: KeyboardEvent) => e.key === 'Enter' && this._add()} />
|
|
117
|
+
<button class="record-action" @click=${(e: MouseEvent) => this._add()} tabindex="-1">
|
|
118
|
+
<md-icon>add</md-icon>
|
|
119
|
+
</button>
|
|
120
|
+
</div>
|
|
121
|
+
`}
|
|
80
122
|
`
|
|
81
123
|
}
|
|
82
124
|
|
|
83
|
-
|
|
84
|
-
|
|
125
|
+
_onChange(e: Event) {
|
|
126
|
+
if (this._changingNow) {
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
this._changingNow = true
|
|
85
131
|
|
|
86
|
-
const
|
|
132
|
+
const input = e.target as HTMLInputElement
|
|
133
|
+
|
|
134
|
+
const record = (e.target as Element).closest('[data-record],[data-record-new]') as HTMLElement
|
|
135
|
+
|
|
136
|
+
if (record.hasAttribute('data-record')) {
|
|
137
|
+
this._build()
|
|
138
|
+
} else if (record.hasAttribute('data-record-new') && input.hasAttribute('data-value')) {
|
|
139
|
+
this._add()
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
this._changingNow = false
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
_build(includeNewRecord?: boolean) {
|
|
146
|
+
const selector = includeNewRecord ? '[data-record],[data-record-new]' : '[data-record]'
|
|
147
|
+
const records = this.renderRoot.querySelectorAll(selector) as NodeListOf<HTMLElement>
|
|
148
|
+
|
|
149
|
+
this.value = Array.from(records)
|
|
150
|
+
.map(record => (record.querySelector('[data-id]')! as HTMLInputElement).value as string)
|
|
151
|
+
.filter(Boolean)
|
|
152
|
+
.sort()
|
|
153
|
+
|
|
154
|
+
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
_add() {
|
|
158
|
+
this._build(true)
|
|
159
|
+
|
|
160
|
+
this.addinput.value = ''
|
|
161
|
+
this.addinput.focus()
|
|
162
|
+
}
|
|
87
163
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const name = li.querySelector('input')?.value
|
|
91
|
-
const node = this.value.find(node => node.id === id)
|
|
164
|
+
_delete(e: MouseEvent) {
|
|
165
|
+
const record = (e.target as Element).closest('[data-record]') as HTMLElement
|
|
92
166
|
|
|
93
|
-
|
|
94
|
-
})
|
|
167
|
+
;(record!.querySelector('[data-id]') as HTMLInputElement)!.value = ''
|
|
95
168
|
|
|
96
|
-
this.
|
|
97
|
-
new CustomEvent('change', {
|
|
98
|
-
bubbles: true,
|
|
99
|
-
composed: true,
|
|
100
|
-
detail: this.value
|
|
101
|
-
})
|
|
102
|
-
)
|
|
169
|
+
this._build()
|
|
103
170
|
}
|
|
104
171
|
}
|
|
@@ -4,23 +4,10 @@ import { html } from 'lit'
|
|
|
4
4
|
import { customElement } from 'lit/decorators.js'
|
|
5
5
|
|
|
6
6
|
import { OxPropertyEditor, PropertySpec } from '@operato/property-editor'
|
|
7
|
-
import { Node } from '../types'
|
|
8
7
|
|
|
9
8
|
@customElement('ox-property-editor-nodes')
|
|
10
9
|
export class PropertyEditorNodes extends OxPropertyEditor {
|
|
11
|
-
editorTemplate(value:
|
|
12
|
-
|
|
13
|
-
// value ||= []
|
|
14
|
-
|
|
15
|
-
// const valueProperty = defaultValue
|
|
16
|
-
// .map(({ name, ...others }) => {
|
|
17
|
-
// const node = value.find(v => v.name == name)
|
|
18
|
-
// if (node) {
|
|
19
|
-
// return { ...others, ...node }
|
|
20
|
-
// }
|
|
21
|
-
// })
|
|
22
|
-
// .filter(Boolean)
|
|
23
|
-
|
|
24
|
-
return html` <ox-input-nodes .value=${value} fullwidth></ox-input-nodes> `
|
|
10
|
+
editorTemplate(value: string[], spec: PropertySpec) {
|
|
11
|
+
return html` <ox-input-nodes .value=${value}></ox-input-nodes> `
|
|
25
12
|
}
|
|
26
13
|
}
|
package/src/mcs-vehicle.ts
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
|
+
import { Properties } from '@hatiolab/things-scene'
|
|
1
2
|
import { LEGEND_VEHICLE, Legend } from './features/mcs-status-default'
|
|
2
3
|
import MCSCarrierHolder from './mcs-carrier-holder'
|
|
4
|
+
import Node from './node'
|
|
3
5
|
|
|
4
6
|
const DIRECTION_GAP = 3
|
|
5
7
|
|
|
8
|
+
function findNode(vehicle: MCSVehicle, nodeId: string, nodeMachine: string) {
|
|
9
|
+
if (!nodeId || !nodeMachine) {
|
|
10
|
+
return null
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const nodes = vehicle.root.findAllById(nodeId).filter(node => node.state.type == 'Node') as Node[]
|
|
14
|
+
|
|
15
|
+
return nodes.find((node: Node) => {
|
|
16
|
+
return node.nodeMachine === nodeMachine
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
6
20
|
/**
|
|
7
21
|
* MCS용 Unit > Transport들의 공통 속성을 정의한 오브젝트
|
|
8
22
|
*/
|
|
@@ -21,6 +35,8 @@ export default class MCSVehicle extends MCSCarrierHolder {
|
|
|
21
35
|
]
|
|
22
36
|
}
|
|
23
37
|
|
|
38
|
+
private lastWaypoint: { NodeId: string; NodeMachine: string } | null = null
|
|
39
|
+
|
|
24
40
|
getLegendFallback(): Legend {
|
|
25
41
|
return LEGEND_VEHICLE
|
|
26
42
|
}
|
|
@@ -77,4 +93,39 @@ export default class MCSVehicle extends MCSCarrierHolder {
|
|
|
77
93
|
super.postrender(ctx)
|
|
78
94
|
// this.renderDirection(ctx)
|
|
79
95
|
}
|
|
96
|
+
|
|
97
|
+
onchangeData(after: Properties, before: Properties): void {
|
|
98
|
+
super.onchangeData(after, before)
|
|
99
|
+
|
|
100
|
+
const { NodeId: beforeNodeId, NodeMachine: beforeNodeMachine } = before.data || {}
|
|
101
|
+
const { NodeId, NodeMachine } = after.data || {}
|
|
102
|
+
|
|
103
|
+
if (
|
|
104
|
+
NodeId === undefined ||
|
|
105
|
+
NodeMachine === undefined ||
|
|
106
|
+
(beforeNodeId === NodeId && beforeNodeMachine === NodeMachine) ||
|
|
107
|
+
(this.lastWaypoint && this.lastWaypoint.NodeId === NodeId && this.lastWaypoint.NodeMachine === NodeMachine)
|
|
108
|
+
) {
|
|
109
|
+
return // not changed
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const afterNode = findNode(this, NodeId, NodeMachine)
|
|
113
|
+
if (!afterNode) {
|
|
114
|
+
console.warn(`Node not found. NodeId: ${NodeId}, NodeMachine: ${NodeMachine}`)
|
|
115
|
+
return
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const beforeNode = this.lastWaypoint
|
|
119
|
+
? findNode(this, this.lastWaypoint.NodeId, this.lastWaypoint.NodeMachine)
|
|
120
|
+
: afterNode
|
|
121
|
+
|
|
122
|
+
// 실제 존재하는 노드 중 가장 최근에 이동한 노드
|
|
123
|
+
this.lastWaypoint = { NodeId, NodeMachine }
|
|
124
|
+
|
|
125
|
+
this.trigger('waypoint', {
|
|
126
|
+
from: beforeNode,
|
|
127
|
+
to: afterNode,
|
|
128
|
+
duration: 5000
|
|
129
|
+
})
|
|
130
|
+
}
|
|
80
131
|
}
|
package/src/node.ts
CHANGED
|
@@ -3,12 +3,24 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { Component, Shape } from '@hatiolab/things-scene'
|
|
6
|
+
import MCSMachine from './mcs-machine'
|
|
6
7
|
|
|
7
8
|
const NATURE = {
|
|
8
9
|
mutable: false,
|
|
9
10
|
resizable: false,
|
|
10
11
|
rotatable: false,
|
|
11
|
-
properties: [
|
|
12
|
+
properties: [
|
|
13
|
+
{
|
|
14
|
+
type: 'string',
|
|
15
|
+
name: 'NodeMachine',
|
|
16
|
+
label: 'node-machine'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
type: 'nodes',
|
|
20
|
+
label: 'nodes',
|
|
21
|
+
name: 'nodes'
|
|
22
|
+
}
|
|
23
|
+
]
|
|
12
24
|
}
|
|
13
25
|
|
|
14
26
|
export default class Node extends Shape {
|
|
@@ -65,6 +77,18 @@ export default class Node extends Shape {
|
|
|
65
77
|
})
|
|
66
78
|
}
|
|
67
79
|
|
|
80
|
+
get nodeMachine() {
|
|
81
|
+
if (this.state.NodeMachine) {
|
|
82
|
+
return this.state.NodeMachine
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const parent = this.parent
|
|
86
|
+
|
|
87
|
+
if (parent && parent instanceof MCSMachine) {
|
|
88
|
+
return parent.state.id
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
68
92
|
contains(x, y) {
|
|
69
93
|
var { cx, cy } = this.state
|
|
70
94
|
|
package/src/oht-line.ts
CHANGED
package/translations/en.json
CHANGED
|
@@ -42,5 +42,7 @@
|
|
|
42
42
|
"label.shuttle-legend-name": "shuttle",
|
|
43
43
|
"label.crane-legend-name": "crane",
|
|
44
44
|
"label.shelf-legend-name": "shelf",
|
|
45
|
-
"label.equipment-legend-name": "equipment"
|
|
45
|
+
"label.equipment-legend-name": "equipment",
|
|
46
|
+
"label.node-machine": "node machine",
|
|
47
|
+
"label.nodes": "nodes"
|
|
46
48
|
}
|
package/translations/ja.json
CHANGED
|
@@ -44,5 +44,7 @@
|
|
|
44
44
|
"label.shuttle-legend-name": "shuttle",
|
|
45
45
|
"label.crane-legend-name": "crane",
|
|
46
46
|
"label.shelf-legend-name": "shelf",
|
|
47
|
-
"label.equipment-legend-name": "equipment"
|
|
47
|
+
"label.equipment-legend-name": "equipment",
|
|
48
|
+
"label.node-machine": "node machine",
|
|
49
|
+
"label.nodes": "nodes"
|
|
48
50
|
}
|
package/translations/ko.json
CHANGED
package/translations/ms.json
CHANGED
|
@@ -44,5 +44,7 @@
|
|
|
44
44
|
"label.shuttle-legend-name": "shuttle",
|
|
45
45
|
"label.crane-legend-name": "crane",
|
|
46
46
|
"label.shelf-legend-name": "shelf",
|
|
47
|
-
"label.equipment-legend-name": "equipment"
|
|
47
|
+
"label.equipment-legend-name": "equipment",
|
|
48
|
+
"label.node-machine": "node machine",
|
|
49
|
+
"label.nodes": "nodes"
|
|
48
50
|
}
|
package/translations/zh.json
CHANGED
|
@@ -44,5 +44,7 @@
|
|
|
44
44
|
"label.shuttle-legend-name": "shuttle",
|
|
45
45
|
"label.crane-legend-name": "crane",
|
|
46
46
|
"label.shelf-legend-name": "shelf",
|
|
47
|
-
"label.equipment-legend-name": "equipment"
|
|
47
|
+
"label.equipment-legend-name": "equipment",
|
|
48
|
+
"label.node-machine": "node machine",
|
|
49
|
+
"label.nodes": "nodes"
|
|
48
50
|
}
|