blob: fd229fae7b996bc46e76ca624e6e102509c155c1 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
namespace SomhairlesDream.Shared
open System
[<RequireQualifiedAccess>]
type RunStatus =
| Idle = 0
| Queued = 1
| Running = 2
| Succeeded = 3
| Failed = 4
| Stale = 5
type Vector3 =
{ X: float
Y: float
Z: float }
type MeshSnapshot =
{ Version: int
Label: string
Vertices: Vector3 array
Faces: int array array }
type LiveSnapshot =
{ ProjectId: string
RunId: string
Status: RunStatus
CurrentVersion: int
TargetVersion: int
HeartbeatAt: DateTimeOffset option
UpdatedAt: DateTimeOffset
Message: string
Mesh: MeshSnapshot option
NextDesignRunScheduled: bool }
module MeshData =
let positionData (mesh: MeshSnapshot) =
mesh.Vertices
|> Array.collect (fun vertex -> [| vertex.X; vertex.Y; vertex.Z |])
let triangleIndices (mesh: MeshSnapshot) =
mesh.Faces
|> Array.collect (fun face ->
if face.Length < 3 then
[||]
else
[| for index in 1 .. face.Length - 2 do
yield face[0]
yield face[index]
yield face[index + 1] |])
module RunState =
let initial projectId runId now =
{ ProjectId = projectId
RunId = runId
Status = RunStatus.Idle
CurrentVersion = 0
TargetVersion = 0
HeartbeatAt = None
UpdatedAt = now
Message = "等待设计运行"
Mesh = None
NextDesignRunScheduled = false }
let start now state =
let targetVersion = state.TargetVersion + 1
{ state with
Status = RunStatus.Running
TargetVersion = targetVersion
HeartbeatAt = Some now
UpdatedAt = now
Message = $"正在生成第 {targetVersion} 版几何"
NextDesignRunScheduled = false }
let heartbeat now state =
if state.Status = RunStatus.Running then
{ state with
HeartbeatAt = Some now
UpdatedAt = now }
else
state
let statusAt timeout now state =
match state.HeartbeatAt with
| Some heartbeatAt when state.Status = RunStatus.Running && now - heartbeatAt > timeout ->
{ state with
Status = RunStatus.Stale
UpdatedAt = now
Message = "心跳超时,等待重连" }
| _ -> state
let publish now mesh state =
{ state with
Status = RunStatus.Succeeded
CurrentVersion = mesh.Version
HeartbeatAt = Some now
UpdatedAt = now
Message = $"已发布{mesh.Label}"
Mesh = Some mesh
NextDesignRunScheduled = false }
|