@shipload/sdk 1.0.0-next.25 → 1.0.0-next.27
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/lib/shipload.d.ts +264 -119
- package/lib/shipload.js +884 -405
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +873 -403
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +35 -21
- package/lib/testing.js +101 -37
- package/lib/testing.js.map +1 -1
- package/lib/testing.m.js +101 -37
- package/lib/testing.m.js.map +1 -1
- package/package.json +1 -1
- package/src/capabilities/craftable.ts +51 -0
- package/src/capabilities/crafting.test.ts +7 -0
- package/src/capabilities/crafting.ts +3 -3
- package/src/capabilities/index.ts +0 -1
- package/src/contracts/platform.ts +21 -1
- package/src/contracts/server.ts +106 -60
- package/src/data/capabilities.ts +5 -0
- package/src/derivation/capabilities.ts +4 -3
- package/src/entities/entity.ts +1 -1
- package/src/entities/makers.ts +14 -5
- package/src/entities/slot-multiplier.ts +2 -0
- package/src/index-module.ts +24 -4
- package/src/managers/actions.ts +16 -1
- package/src/managers/construction-types.ts +2 -1
- package/src/managers/construction.ts +126 -70
- package/src/scheduling/accessor.ts +65 -23
- package/src/scheduling/availability.ts +108 -0
- package/src/scheduling/energy.ts +18 -11
- package/src/scheduling/lane-core.ts +130 -0
- package/src/scheduling/lanes.ts +60 -0
- package/src/scheduling/projection.ts +30 -54
- package/src/scheduling/schedule.ts +236 -116
- package/src/travel/travel.ts +21 -16
- package/src/types/capabilities.ts +1 -0
- package/src/capabilities/loading.ts +0 -8
|
@@ -55,7 +55,7 @@ export const GATHERER_DEPTH_TABLE: readonly GathererDepthParams[] = [
|
|
|
55
55
|
{floor: 46000, slope: 12},
|
|
56
56
|
{floor: 53500, slope: 10},
|
|
57
57
|
{floor: 60000, slope: 5},
|
|
58
|
-
{floor:
|
|
58
|
+
{floor: 63537, slope: 2},
|
|
59
59
|
]
|
|
60
60
|
|
|
61
61
|
export const GATHERER_DEPTH_MAX_TIER = 10
|
|
@@ -175,6 +175,7 @@ import {decodeCraftedItemStats} from './crafting'
|
|
|
175
175
|
import {
|
|
176
176
|
applySlotMultiplier,
|
|
177
177
|
clampUint16,
|
|
178
|
+
clampUint32,
|
|
178
179
|
getSlotAmp,
|
|
179
180
|
type InstalledModule,
|
|
180
181
|
} from '../entities/slot-multiplier'
|
|
@@ -346,8 +347,8 @@ export function computeEntityCapabilities(
|
|
|
346
347
|
}
|
|
347
348
|
if (hasGenerator) {
|
|
348
349
|
result.generator = {
|
|
349
|
-
capacity:
|
|
350
|
-
recharge:
|
|
350
|
+
capacity: clampUint32(totalGenCapacity),
|
|
351
|
+
recharge: clampUint32(totalGenRecharge),
|
|
351
352
|
}
|
|
352
353
|
}
|
|
353
354
|
if (hasGatherer) {
|
package/src/entities/entity.ts
CHANGED
package/src/entities/makers.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {getItem} from '../data/catalog'
|
|
|
11
11
|
import {getModuleCapabilityType, moduleAccepts, moduleSlotTypeToCode} from '../capabilities/modules'
|
|
12
12
|
import {computeEntityCapabilities} from '../derivation/capabilities'
|
|
13
13
|
import {packedModulesToInstalled} from './slot-multiplier'
|
|
14
|
+
import {LANE_MOBILITY} from '../scheduling/schedule'
|
|
14
15
|
|
|
15
16
|
export interface PackedModuleInput {
|
|
16
17
|
itemId: number
|
|
@@ -29,6 +30,7 @@ export interface EntityStateInput {
|
|
|
29
30
|
energy?: number
|
|
30
31
|
modules?: PackedModuleInput[]
|
|
31
32
|
schedule?: ServerContract.Types.schedule
|
|
33
|
+
lanes?: ServerContract.Types.lane[]
|
|
32
34
|
cargo?: ServerContract.Types.cargo_item[]
|
|
33
35
|
}
|
|
34
36
|
|
|
@@ -86,6 +88,17 @@ export function makeEntity(packedItemId: number, state: EntityStateInput): Entit
|
|
|
86
88
|
const layout = getEntityLayout(packedItemId)?.slots ?? []
|
|
87
89
|
const mods = state.modules ?? []
|
|
88
90
|
|
|
91
|
+
const lanes =
|
|
92
|
+
state.lanes ??
|
|
93
|
+
(state.schedule
|
|
94
|
+
? [
|
|
95
|
+
ServerContract.Types.lane.from({
|
|
96
|
+
lane_key: UInt8.from(LANE_MOBILITY),
|
|
97
|
+
schedule: state.schedule,
|
|
98
|
+
}),
|
|
99
|
+
]
|
|
100
|
+
: [])
|
|
101
|
+
|
|
89
102
|
const info: Record<string, unknown> = {
|
|
90
103
|
type: template.kind,
|
|
91
104
|
id: UInt64.from(state.id),
|
|
@@ -95,14 +108,10 @@ export function makeEntity(packedItemId: number, state: EntityStateInput): Entit
|
|
|
95
108
|
item_id: UInt16.from(state.itemId ?? template.itemId),
|
|
96
109
|
cargomass: UInt32.from(state.cargomass ?? 0),
|
|
97
110
|
cargo: state.cargo || [],
|
|
98
|
-
|
|
99
|
-
current_task_elapsed: UInt32.from(0),
|
|
100
|
-
current_task_remaining: UInt32.from(0),
|
|
101
|
-
pending_tasks: [],
|
|
111
|
+
lanes,
|
|
102
112
|
}
|
|
103
113
|
|
|
104
114
|
if (state.energy !== undefined) info.energy = UInt16.from(state.energy)
|
|
105
|
-
if (state.schedule) info.schedule = state.schedule
|
|
106
115
|
|
|
107
116
|
if (kind === 'container') {
|
|
108
117
|
info.modules = []
|
|
@@ -28,6 +28,8 @@ export function clampUint16(value: number): number {
|
|
|
28
28
|
return Math.min(value, U16_MAX)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
export const clampUint32 = (v: number): number => Math.min(Math.max(Math.floor(v), 0), 4294967295)
|
|
32
|
+
|
|
31
33
|
export function applySlotMultiplier(value: number, outputPct: number): number {
|
|
32
34
|
return clampUint16(Math.floor((value * outputPct) / 100))
|
|
33
35
|
}
|
package/src/index-module.ts
CHANGED
|
@@ -28,6 +28,7 @@ export type movement_stats = ServerContract.Types.movement_stats
|
|
|
28
28
|
export type energy_stats = ServerContract.Types.energy_stats
|
|
29
29
|
export type loader_stats = ServerContract.Types.loader_stats
|
|
30
30
|
export type schedule = ServerContract.Types.schedule
|
|
31
|
+
export type lane = ServerContract.Types.lane
|
|
31
32
|
export type task = ServerContract.Types.task
|
|
32
33
|
export type cargo_item = ServerContract.Types.cargo_item
|
|
33
34
|
export type entity_row = ServerContract.Types.entity_row
|
|
@@ -177,7 +178,19 @@ export type {
|
|
|
177
178
|
} from './travel/travel'
|
|
178
179
|
|
|
179
180
|
export * as schedule from './scheduling/schedule'
|
|
180
|
-
export
|
|
181
|
+
export {LANE_MOBILITY, LANE_BARRIER} from './scheduling/schedule'
|
|
182
|
+
export type {
|
|
183
|
+
ScheduleData,
|
|
184
|
+
LaneView,
|
|
185
|
+
OrderedTask,
|
|
186
|
+
ResolvedEvent,
|
|
187
|
+
} from './scheduling/schedule'
|
|
188
|
+
export {
|
|
189
|
+
candidateLaneCompletesAt,
|
|
190
|
+
laneKeyForModule,
|
|
191
|
+
rawScheduleEnd,
|
|
192
|
+
workerLaneKey,
|
|
193
|
+
} from './scheduling/lanes'
|
|
181
194
|
export {ScheduleAccessor, createScheduleAccessor} from './scheduling/accessor'
|
|
182
195
|
export {InventoryAccessor, createInventoryAccessor} from './entities/inventory-accessor'
|
|
183
196
|
export type {HasCargo} from './entities/inventory-accessor'
|
|
@@ -191,13 +204,11 @@ export {
|
|
|
191
204
|
createProjectedEntity,
|
|
192
205
|
projectEntity,
|
|
193
206
|
projectEntityAt,
|
|
194
|
-
|
|
195
|
-
projectFromCurrentStateAt,
|
|
207
|
+
projectRemainingAt,
|
|
196
208
|
validateSchedule,
|
|
197
209
|
} from './scheduling/projection'
|
|
198
210
|
export type {
|
|
199
211
|
Projectable,
|
|
200
|
-
ProjectableSnapshot,
|
|
201
212
|
ProjectedEntity,
|
|
202
213
|
ProjectionOptions,
|
|
203
214
|
} from './scheduling/projection'
|
|
@@ -205,6 +216,15 @@ export type {
|
|
|
205
216
|
export {taskCargoChanges} from './scheduling/task-cargo'
|
|
206
217
|
export type {TaskCargoChange, TaskCargoDirection} from './scheduling/task-cargo'
|
|
207
218
|
|
|
219
|
+
export {
|
|
220
|
+
projectedCargoAvailableAt,
|
|
221
|
+
availableForItem,
|
|
222
|
+
cargoReadyAt,
|
|
223
|
+
taskCargoEffect,
|
|
224
|
+
} from './scheduling/availability'
|
|
225
|
+
|
|
226
|
+
export {maxCraftable} from './capabilities/craftable'
|
|
227
|
+
|
|
208
228
|
export {energyAtTime} from './scheduling/energy'
|
|
209
229
|
|
|
210
230
|
export * from './types/capabilities'
|
package/src/managers/actions.ts
CHANGED
|
@@ -65,13 +65,22 @@ export class ActionsManager extends BaseManager {
|
|
|
65
65
|
return this.server.action('resolve', params)
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
cancel(entityId: UInt64Type, count: UInt64Type): Action {
|
|
68
|
+
cancel(entityId: UInt64Type, laneKey: number, count: UInt64Type): Action {
|
|
69
69
|
return this.server.action('cancel', {
|
|
70
70
|
id: UInt64.from(entityId),
|
|
71
|
+
lane_key: UInt8.from(laneKey),
|
|
71
72
|
count: UInt64.from(count),
|
|
72
73
|
})
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
retarget(sourceId: UInt64Type, taskIndex: UInt64Type, newDestId: UInt64Type): Action {
|
|
77
|
+
return this.server.action('retarget', {
|
|
78
|
+
source_id: UInt64.from(sourceId),
|
|
79
|
+
task_index: UInt64.from(taskIndex),
|
|
80
|
+
new_dest_id: UInt64.from(newDestId),
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
75
84
|
recharge(entityId: UInt64Type): Action {
|
|
76
85
|
return this.server.action('recharge', {
|
|
77
86
|
id: UInt64.from(entityId),
|
|
@@ -252,6 +261,12 @@ export class ActionsManager extends BaseManager {
|
|
|
252
261
|
})
|
|
253
262
|
}
|
|
254
263
|
|
|
264
|
+
claimStarter(owner: NameType): Action {
|
|
265
|
+
return this.server.action('claimstarter', {
|
|
266
|
+
owner: Name.from(owner),
|
|
267
|
+
})
|
|
268
|
+
}
|
|
269
|
+
|
|
255
270
|
async wrapEntity(
|
|
256
271
|
owner: NameType,
|
|
257
272
|
entityId: UInt64Type,
|
|
@@ -4,6 +4,7 @@ import type {ServerContract} from '../contracts'
|
|
|
4
4
|
import {PlotManager} from './plot'
|
|
5
5
|
import {getItem} from '../data/catalog'
|
|
6
6
|
import {calc_craft_duration} from '../capabilities/crafting'
|
|
7
|
+
import {getLanes, getTasks} from '../scheduling/schedule'
|
|
7
8
|
import {TaskType} from '../types'
|
|
8
9
|
import type {
|
|
9
10
|
BuildableTarget,
|
|
@@ -94,43 +95,43 @@ export class ConstructionManager extends BaseManager {
|
|
|
94
95
|
const buckets = new Map<string, Map<string, InboundTransfer>>()
|
|
95
96
|
const nowMs = now.getTime()
|
|
96
97
|
for (const entity of entities) {
|
|
97
|
-
const schedule = entity.schedule
|
|
98
|
-
if (!schedule) continue
|
|
99
98
|
const entityIdStr = entity.id.toString()
|
|
100
99
|
const sourceName = entity.entity_name || entityIdStr
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
existing
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
100
|
+
for (const lane of getLanes(entity)) {
|
|
101
|
+
const startedMs = lane.schedule.started.toDate().getTime()
|
|
102
|
+
let cumulativeSec = 0
|
|
103
|
+
for (const task of lane.schedule.tasks) {
|
|
104
|
+
cumulativeSec += task.duration.toNumber()
|
|
105
|
+
if (!isTransferTask(task)) continue
|
|
106
|
+
if (!task.entitytarget) continue
|
|
107
|
+
const projectedEndMs = startedMs + cumulativeSec * 1000
|
|
108
|
+
if (projectedEndMs < nowMs) continue
|
|
109
|
+
const targetIdStr = task.entitytarget.entity_id.toString()
|
|
110
|
+
const etaSeconds = Math.max(0, Math.round((projectedEndMs - nowMs) / 1000))
|
|
111
|
+
let perTarget = buckets.get(targetIdStr)
|
|
112
|
+
if (!perTarget) {
|
|
113
|
+
perTarget = new Map()
|
|
114
|
+
buckets.set(targetIdStr, perTarget)
|
|
115
|
+
}
|
|
116
|
+
for (const c of task.cargo) {
|
|
117
|
+
const itemId = c.item_id.toNumber()
|
|
118
|
+
const quantity = c.quantity.toNumber()
|
|
119
|
+
if (quantity === 0) continue
|
|
120
|
+
const key = `${entityIdStr}#${itemId}`
|
|
121
|
+
const existing = perTarget.get(key)
|
|
122
|
+
if (existing) {
|
|
123
|
+
existing.quantity += quantity
|
|
124
|
+
existing.etaSeconds = Math.min(existing.etaSeconds, etaSeconds)
|
|
125
|
+
} else {
|
|
126
|
+
perTarget.set(key, {
|
|
127
|
+
sourceEntityId: entity.id,
|
|
128
|
+
sourceEntityType: entity.type,
|
|
129
|
+
sourceName,
|
|
130
|
+
itemId,
|
|
131
|
+
quantity,
|
|
132
|
+
etaSeconds,
|
|
133
|
+
})
|
|
134
|
+
}
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
}
|
|
@@ -142,51 +143,107 @@ export class ConstructionManager extends BaseManager {
|
|
|
142
143
|
return out
|
|
143
144
|
}
|
|
144
145
|
|
|
146
|
+
private plotReservation(
|
|
147
|
+
plot: ServerContract.Types.entity_info,
|
|
148
|
+
now: Date
|
|
149
|
+
): {
|
|
150
|
+
builderId: UInt64
|
|
151
|
+
group?: UInt64
|
|
152
|
+
startsAt: number
|
|
153
|
+
completesAt: number
|
|
154
|
+
hasStarted: boolean
|
|
155
|
+
} | null {
|
|
156
|
+
for (const lane of getLanes(plot)) {
|
|
157
|
+
const startedMs = lane.schedule.started.toDate().getTime()
|
|
158
|
+
let startSec = 0
|
|
159
|
+
for (const task of lane.schedule.tasks) {
|
|
160
|
+
if (task.type.toNumber() === TaskType.RESERVED) {
|
|
161
|
+
if (!task.entitytarget) return null
|
|
162
|
+
const startsAt = startedMs + startSec * 1000
|
|
163
|
+
const completesAt = startsAt + task.duration.toNumber() * 1000
|
|
164
|
+
return {
|
|
165
|
+
builderId: task.entitytarget.entity_id,
|
|
166
|
+
group: task.entitygroup ?? undefined,
|
|
167
|
+
startsAt,
|
|
168
|
+
completesAt,
|
|
169
|
+
hasStarted: startsAt <= now.getTime(),
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
startSec += task.duration.toNumber()
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return null
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
private builderCancelability(
|
|
179
|
+
builder: ServerContract.Types.entity_info | undefined,
|
|
180
|
+
group: UInt64 | undefined
|
|
181
|
+
): {cancelable: boolean; blockingTaskCount: number} {
|
|
182
|
+
if (!builder || group === undefined) {
|
|
183
|
+
return {cancelable: false, blockingTaskCount: 0}
|
|
184
|
+
}
|
|
185
|
+
for (const lane of getLanes(builder)) {
|
|
186
|
+
const tasks = lane.schedule.tasks
|
|
187
|
+
const buildIdx = tasks.findIndex(
|
|
188
|
+
(t) =>
|
|
189
|
+
t.type.toNumber() === TaskType.BUILDPLOT &&
|
|
190
|
+
t.entitygroup !== undefined &&
|
|
191
|
+
t.entitygroup.equals(group)
|
|
192
|
+
)
|
|
193
|
+
if (buildIdx < 0) continue
|
|
194
|
+
const trailing = tasks.length - 1 - buildIdx
|
|
195
|
+
return {cancelable: trailing === 0, blockingTaskCount: trailing}
|
|
196
|
+
}
|
|
197
|
+
return {cancelable: false, blockingTaskCount: 0}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private buildFromReservation(
|
|
201
|
+
res: {
|
|
202
|
+
builderId: UInt64
|
|
203
|
+
group?: UInt64
|
|
204
|
+
startsAt: number
|
|
205
|
+
completesAt: number
|
|
206
|
+
hasStarted: boolean
|
|
207
|
+
},
|
|
208
|
+
builder: ServerContract.Types.entity_info | undefined
|
|
209
|
+
): ScheduledBuild {
|
|
210
|
+
const {cancelable, blockingTaskCount} = this.builderCancelability(builder, res.group)
|
|
211
|
+
return {
|
|
212
|
+
shipId: res.builderId,
|
|
213
|
+
shipName: builder?.entity_name || res.builderId.toString(),
|
|
214
|
+
hasStarted: res.hasStarted,
|
|
215
|
+
startsAt: res.startsAt,
|
|
216
|
+
completesAt: res.completesAt,
|
|
217
|
+
cancelable,
|
|
218
|
+
blockingTaskCount,
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
145
222
|
scheduledBuildFor(
|
|
146
|
-
|
|
223
|
+
plot: ServerContract.Types.entity_info,
|
|
147
224
|
entities: ServerContract.Types.entity_info[],
|
|
148
225
|
now: Date
|
|
149
226
|
): ScheduledBuild | null {
|
|
150
|
-
|
|
227
|
+
const res = this.plotReservation(plot, now)
|
|
228
|
+
if (!res) return null
|
|
229
|
+
const builder = entities.find((e) => e.id.equals(res.builderId))
|
|
230
|
+
return this.buildFromReservation(res, builder)
|
|
151
231
|
}
|
|
152
232
|
|
|
153
233
|
scheduledBuildsByTarget(
|
|
154
234
|
entities: ServerContract.Types.entity_info[],
|
|
155
235
|
now: Date
|
|
156
236
|
): Map<string, ScheduledBuild> {
|
|
157
|
-
const
|
|
158
|
-
const
|
|
237
|
+
const byId = new Map(entities.map((e) => [e.id.toString(), e]))
|
|
238
|
+
const out = new Map<string, ScheduledBuild>()
|
|
159
239
|
for (const entity of entities) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
for (let i = 0; i < tasks.length; i++) {
|
|
166
|
-
const task = tasks[i]
|
|
167
|
-
const startSec = cumulativeSec
|
|
168
|
-
cumulativeSec += task.duration.toNumber()
|
|
169
|
-
if (task.type.toNumber() !== TaskType.BUILDPLOT) continue
|
|
170
|
-
if (!task.entitytarget) continue
|
|
171
|
-
const completesAt = startedMs + cumulativeSec * 1000
|
|
172
|
-
if (completesAt < nowMs) continue
|
|
173
|
-
const startsAt = startedMs + startSec * 1000
|
|
174
|
-
const targetId = task.entitytarget.entity_id.toString()
|
|
175
|
-
const candidate: ScheduledBuild = {
|
|
176
|
-
shipId: entity.id,
|
|
177
|
-
shipName: entity.entity_name || entity.id.toString(),
|
|
178
|
-
hasStarted: startsAt <= nowMs,
|
|
179
|
-
startsAt,
|
|
180
|
-
completesAt,
|
|
181
|
-
trailingCancelCount: tasks.length - 1 - i,
|
|
182
|
-
}
|
|
183
|
-
const existing = best.get(targetId)
|
|
184
|
-
if (!existing || candidate.completesAt < existing.completesAt) {
|
|
185
|
-
best.set(targetId, candidate)
|
|
186
|
-
}
|
|
187
|
-
}
|
|
240
|
+
if (entity.type.toString() !== 'plot') continue
|
|
241
|
+
const res = this.plotReservation(entity, now)
|
|
242
|
+
if (!res) continue
|
|
243
|
+
const builder = byId.get(res.builderId.toString())
|
|
244
|
+
out.set(entity.id.toString(), this.buildFromReservation(res, builder))
|
|
188
245
|
}
|
|
189
|
-
return
|
|
246
|
+
return out
|
|
190
247
|
}
|
|
191
248
|
|
|
192
249
|
reservationsFrom(
|
|
@@ -303,9 +360,8 @@ function isTransferTask(task: ServerContract.Types.task): boolean {
|
|
|
303
360
|
}
|
|
304
361
|
|
|
305
362
|
function reservationsOf(source: ServerContract.Types.entity_info): Reservation[] {
|
|
306
|
-
if (!source.schedule) return []
|
|
307
363
|
const out = new Map<string, Reservation>()
|
|
308
|
-
for (const task of source
|
|
364
|
+
for (const task of getTasks(source)) {
|
|
309
365
|
if (!isTransferTask(task)) continue
|
|
310
366
|
if (!task.entitytarget) continue
|
|
311
367
|
const targetType = task.entitytarget.entity_type
|
|
@@ -1,86 +1,128 @@
|
|
|
1
1
|
import type {ServerContract} from '../contracts'
|
|
2
2
|
import type {TaskType} from '../types'
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import * as core from './lane-core'
|
|
4
|
+
import {
|
|
5
|
+
activeTasks,
|
|
6
|
+
getLane,
|
|
7
|
+
getLanes,
|
|
8
|
+
hasSchedule,
|
|
9
|
+
isIdle,
|
|
10
|
+
LANE_MOBILITY,
|
|
11
|
+
type LaneView,
|
|
12
|
+
type ScheduleData,
|
|
13
|
+
} from './schedule'
|
|
5
14
|
|
|
6
15
|
type Task = ServerContract.Types.task
|
|
7
16
|
|
|
8
17
|
export class ScheduleAccessor {
|
|
9
|
-
|
|
18
|
+
private _laneResolved = false
|
|
19
|
+
private _lane: LaneView | undefined
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
private entity: ScheduleData,
|
|
23
|
+
private laneKey: number = LANE_MOBILITY
|
|
24
|
+
) {}
|
|
25
|
+
|
|
26
|
+
private get lane(): LaneView | undefined {
|
|
27
|
+
if (!this._laneResolved) {
|
|
28
|
+
this._lane = getLane(this.entity, this.laneKey)
|
|
29
|
+
this._laneResolved = true
|
|
30
|
+
}
|
|
31
|
+
return this._lane
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
forLane(laneKey: number): ScheduleAccessor {
|
|
35
|
+
return new ScheduleAccessor(this.entity, laneKey)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get lanes(): LaneView[] {
|
|
39
|
+
return getLanes(this.entity)
|
|
40
|
+
}
|
|
10
41
|
|
|
11
42
|
get hasSchedule(): boolean {
|
|
12
|
-
return
|
|
43
|
+
return hasSchedule(this.entity)
|
|
13
44
|
}
|
|
14
45
|
|
|
15
46
|
get isIdle(): boolean {
|
|
16
|
-
return
|
|
47
|
+
return isIdle(this.entity)
|
|
17
48
|
}
|
|
18
49
|
|
|
19
50
|
get tasks(): Task[] {
|
|
20
|
-
return schedule.
|
|
51
|
+
return this.lane?.schedule.tasks ?? []
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
activeTasks(now: Date): Task[] {
|
|
55
|
+
return activeTasks(this.entity, now)
|
|
21
56
|
}
|
|
22
57
|
|
|
23
58
|
duration(): number {
|
|
24
|
-
return
|
|
59
|
+
return this.lane ? core.laneDuration(this.lane.schedule) : 0
|
|
25
60
|
}
|
|
26
61
|
|
|
27
62
|
elapsed(now: Date): number {
|
|
28
|
-
return
|
|
63
|
+
return this.lane ? core.laneElapsed(this.lane.schedule, now) : 0
|
|
29
64
|
}
|
|
30
65
|
|
|
31
66
|
remaining(now: Date): number {
|
|
32
|
-
return
|
|
67
|
+
return this.lane ? core.laneRemaining(this.lane.schedule, now) : 0
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
startsIn(now: Date): number {
|
|
71
|
+
return this.lane ? core.laneStartsIn(this.lane.schedule, now) : 0
|
|
33
72
|
}
|
|
34
73
|
|
|
35
74
|
complete(now: Date): boolean {
|
|
36
|
-
return
|
|
75
|
+
return this.lane ? core.laneComplete(this.lane.schedule, now) : false
|
|
37
76
|
}
|
|
38
77
|
|
|
39
78
|
currentTaskIndex(now: Date): number {
|
|
40
|
-
return
|
|
79
|
+
return this.lane ? core.currentTaskIndexForLane(this.lane.schedule, now) : -1
|
|
41
80
|
}
|
|
42
81
|
|
|
43
82
|
currentTask(now: Date): Task | undefined {
|
|
44
|
-
return
|
|
83
|
+
return this.lane ? core.currentTask(this.lane.schedule, now) : undefined
|
|
45
84
|
}
|
|
46
85
|
|
|
47
86
|
currentTaskType(now: Date): TaskType | undefined {
|
|
48
|
-
return
|
|
87
|
+
return this.lane ? core.currentTaskType(this.lane.schedule, now) : undefined
|
|
49
88
|
}
|
|
50
89
|
|
|
51
90
|
taskStartTime(index: number): number {
|
|
52
|
-
return
|
|
91
|
+
return this.lane ? core.laneTaskStartTime(this.lane.schedule, index) : 0
|
|
53
92
|
}
|
|
54
93
|
|
|
55
94
|
taskElapsed(index: number, now: Date): number {
|
|
56
|
-
return
|
|
95
|
+
return this.lane ? core.laneTaskElapsed(this.lane.schedule, index, now) : 0
|
|
57
96
|
}
|
|
58
97
|
|
|
59
98
|
taskRemaining(index: number, now: Date): number {
|
|
60
|
-
return
|
|
99
|
+
return this.lane ? core.laneTaskRemaining(this.lane.schedule, index, now) : 0
|
|
61
100
|
}
|
|
62
101
|
|
|
63
102
|
taskComplete(index: number, now: Date): boolean {
|
|
64
|
-
return
|
|
103
|
+
return this.lane ? core.laneTaskComplete(this.lane.schedule, index, now) : false
|
|
65
104
|
}
|
|
66
105
|
|
|
67
106
|
taskInProgress(index: number, now: Date): boolean {
|
|
68
|
-
return
|
|
107
|
+
return this.lane ? core.laneTaskInProgress(this.lane.schedule, index, now) : false
|
|
69
108
|
}
|
|
70
109
|
|
|
71
110
|
currentTaskProgress(now: Date): number {
|
|
72
|
-
return
|
|
111
|
+
return this.lane ? core.currentTaskProgress(this.lane.schedule, now) : 0
|
|
73
112
|
}
|
|
74
113
|
|
|
75
114
|
currentTaskProgressFloat(now: Date): number {
|
|
76
|
-
return
|
|
115
|
+
return this.lane ? core.currentTaskProgressFloatForLane(this.lane.schedule, now) : 0
|
|
77
116
|
}
|
|
78
117
|
|
|
79
118
|
progress(now: Date): number {
|
|
80
|
-
return
|
|
119
|
+
return this.lane ? core.laneProgress(this.lane.schedule, now) : 0
|
|
81
120
|
}
|
|
82
121
|
}
|
|
83
122
|
|
|
84
|
-
export function createScheduleAccessor(
|
|
85
|
-
|
|
123
|
+
export function createScheduleAccessor(
|
|
124
|
+
entity: ScheduleData,
|
|
125
|
+
laneKey: number = LANE_MOBILITY
|
|
126
|
+
): ScheduleAccessor {
|
|
127
|
+
return new ScheduleAccessor(entity, laneKey)
|
|
86
128
|
}
|