Skip to content

Commit

Permalink
making refreshTreatments more efficient (only for patients there visi…
Browse files Browse the repository at this point in the history
…bleStatus changed)
  • Loading branch information
anonym-HPI committed Jul 3, 2022
1 parent 30e5c84 commit ebbbad2
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 39 deletions.
1 change: 1 addition & 0 deletions backend/src/exercise/exercise-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ export class ExerciseWrapper extends NormalType<
/**
* refresh every {@link refreshTreatmentInterval} * {@link tickInterval} ms seconds
*/
// TODO: Refactor this so that `refreshTreatments` is done the same way
refreshTreatments:
this.tickCounter % this.refreshTreatmentInterval === 0,
tickInterval: this.tickInterval,
Expand Down
75 changes: 41 additions & 34 deletions shared/src/models/patient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export class Patient {
@ValidateNested()
@Type(() => PretriageInformation)
public readonly pretriageInformation: PretriageInformation;

/**
* A description of the expected patient behaviour over time
* For the trainer
Expand All @@ -56,45 +57,26 @@ export class Patient {
@IsString()
public readonly realStatus: PatientStatus;

/**
* TODO: maybe use getter and setter for {@link needsNewCalculateTreatments} and combine it with getVisibleStatus
* when visibleStatus would change, set this to true, for refreshTreatments in exerciseTickAction
* will be set to false when next calculateTreatments was called for this patient
*/
@IsBoolean()
public readonly needsNewCalculateTreatments: boolean = false;

@ValidateNested()
@Type(() => ImageProperties)
public readonly image: ImageProperties;

/**
* @deprecated Use {@link create} instead
*/
constructor(
// TODO: Specify patient data (e.g. injuries, name, etc.)
personalInformation: PersonalInformation,
biometricInformation: BiometricInformation,
pretriageInformation: PretriageInformation,
patientStatusCode: PatientStatusCode,
pretriageStatus: PatientStatus,
realStatus: PatientStatus,
healthStates: { readonly [stateId: UUID]: PatientHealthState },
currentHealthStateId: UUID,
image: ImageProperties,
health: HealthPoints
) {
this.personalInformation = personalInformation;
this.biometricInformation = biometricInformation;
this.pretriageInformation = pretriageInformation;
this.patientStatusCode = patientStatusCode;
this.pretriageStatus = pretriageStatus;
this.realStatus = realStatus;
this.healthStates = healthStates;
this.currentHealthStateId = currentHealthStateId;
this.image = image;
this.health = health;
}

/**
* Exclusive-or to {@link vehicleId}
*/
@ValidateNested()
@Type(() => Position)
@IsOptional()
public readonly position?: Position;

/**
* Exclusive-or to {@link position}
*/
Expand All @@ -118,6 +100,7 @@ export class Patient {
*/
@IsUUID(4, uuidValidationOptions)
public readonly currentHealthStateId: UUID;

/**
* See {@link HealthPoints} for context of this property.
*/
Expand Down Expand Up @@ -150,23 +133,47 @@ export class Patient {
@Min(0)
public treatmentTime = 0;

static readonly create = getCreate(this);

/**
* The time that is needed for personnel to automatically pretriage the patient
* in milliseconds
*/
private static readonly pretriageTimeThreshold: number = 2 * 60 * 1000;

/**
* @deprecated Use {@link create} instead
*/
constructor(
// TODO: Specify patient data (e.g. injuries, name, etc.)
personalInformation: PersonalInformation,
biometricInformation: BiometricInformation,
pretriageInformation: PretriageInformation,
patientStatusCode: PatientStatusCode,
pretriageStatus: PatientStatus,
realStatus: PatientStatus,
healthStates: { readonly [stateId: UUID]: PatientHealthState },
currentHealthStateId: UUID,
image: ImageProperties,
health: HealthPoints
) {
this.personalInformation = personalInformation;
this.biometricInformation = biometricInformation;
this.pretriageInformation = pretriageInformation;
this.patientStatusCode = patientStatusCode;
this.pretriageStatus = pretriageStatus;
this.realStatus = realStatus;
this.healthStates = healthStates;
this.currentHealthStateId = currentHealthStateId;
this.image = image;
this.health = health;
}

static readonly create = getCreate(this);

static getVisibleStatus(
patient: Patient,
pretriageEnabled: boolean,
bluePatientsEnabled: boolean
) {
// if (patient.treatmentTime !== 0) {
// console.log(patient);
// patient.treatmentTime = 0;
// }
const status =
!pretriageEnabled ||
patient.treatmentTime >= this.pretriageTimeThreshold
Expand Down
38 changes: 34 additions & 4 deletions shared/src/store/action-reducers/exercise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import {
ValidateNested,
} from 'class-validator';
import { countBy } from 'lodash-es';
import type { Client, Vehicle, Patient } from '../../models';
import { Personnel, Viewport } from '../../models';
import type { Client, Vehicle } from '../../models';
import { Patient, Personnel, Viewport } from '../../models';
import { StatusHistoryEntry } from '../../models/status-history-entry';
import { getStatus } from '../../models/utils';
import type { AreaStatistics } from '../../models/utils/area-statistics';
Expand Down Expand Up @@ -114,14 +114,41 @@ export namespace ExerciseActionReducers {
// Refresh patient status
patientUpdates.forEach((patientUpdate) => {
const currentPatient = draftState.patients[patientUpdate.id];

const visibleStatusBefore = Patient.getVisibleStatus(
currentPatient,
draftState.configuration.pretriageEnabled,
draftState.configuration.bluePatientsEnabled
);

currentPatient.currentHealthStateId = patientUpdate.nextStateId;
currentPatient.health = patientUpdate.nextHealthPoints;
currentPatient.stateTime = patientUpdate.nextStateTime;
currentPatient.treatmentTime = patientUpdate.treatmentTime;
currentPatient.realStatus = getStatus(currentPatient.health);

// Refresh treatments
if (refreshTreatments) {
/**
* if visibleStatus would change setting {@link needsNewCalculateTreatments} to true,
* as when {@link refreshTreatments} is also true, this patient needs new treatment calculation
*/
if (
visibleStatusBefore !==
Patient.getVisibleStatus(
currentPatient,
draftState.configuration.pretriageEnabled,
draftState.configuration.bluePatientsEnabled
)
) {
currentPatient.needsNewCalculateTreatments = true;
}

/**
* Refresh treatments of this patient every refreshTreatmentInterval and only when the visibleStatus of a patient really changed
*/
if (
refreshTreatments &&
currentPatient.needsNewCalculateTreatments
) {
calculateTreatments(
draftState,
currentPatient,
Expand All @@ -130,6 +157,9 @@ export namespace ExerciseActionReducers {
personnelDataStructure,
materialsDataStructure
);
/**
* calculateTreatments() will set {@link needsNewCalculateTreatments} to false again
*/
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ export function calculateTreatments(
);
}
// element is patient: calculating for every personnel and material around the patient position(s)
// TODO: seems to not work (patient moving, adding and probably deleting)

// if patient moved (has startPosition and targetPosition)
if (isPositionArray(positions)) {
// recalculating catering for every personnel around the position a patient was
Expand Down Expand Up @@ -372,6 +372,12 @@ export function calculateTreatments(
elementIdsToBeSkipped
);
}

/**
* patient got new treatment and updated all possible personnel and material, therefore setting {@link needsNewCalculateTreatments} to false
*/
getElement(state, 'patients', element.id).needsNewCalculateTreatments =
false;
}
}

Expand Down

0 comments on commit ebbbad2

Please sign in to comment.