Skip to content

Commit

Permalink
Merge pull request #199 from hpi-sam/152-n05-action-requirements
Browse files Browse the repository at this point in the history
152 n05 action requirements
  • Loading branch information
Wolkenfarmer authored May 22, 2024
2 parents 1297084 + e760316 commit 62e9557
Show file tree
Hide file tree
Showing 43 changed files with 2,082 additions and 1,117 deletions.
97 changes: 68 additions & 29 deletions backend/dps_training_k/game/channel_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class ChannelEventTypes:
EXERCISE_END_EVENT = "exercise.end.event"
ACTION_CONFIRMATION_EVENT = "action.confirmation.event"
ACTION_LIST_EVENT = "action.list.event"
ACTION_CHECK_CHANGED_EVENT = "action.check.changed.event"
LOG_UPDATE_EVENT = "log.update.event"


Expand All @@ -37,6 +38,7 @@ def save_and_notify(cls, obj, changes, save_origin, *args, **kwargs):
save_origin.save(*args, **kwargs)
cls.dispatch_event(obj, changes, is_updated)
cls.create_trainer_log(obj, changes, is_updated)
cls._notify_action_check_update(cls.get_exercise(obj))

@classmethod
def delete_and_notify(cls, obj, changes):
Expand All @@ -53,10 +55,18 @@ def _notify_group(cls, group_channel_name, event):
"""
async_to_sync(get_channel_layer().group_send)(group_channel_name, event)

@classmethod
def get_exercise(cls, obj):
raise NotImplementedError("Method get_exercise must be implemented by subclass")

@classmethod
def get_group_name(cls, obj):
return f"{obj.__class__.__name__}_{obj.id}"

@classmethod
def get_live_group_name(cls, exercise):
return f"{cls.__name__}_{exercise.id}_live"

@classmethod
def dispatch_event(cls, obj, changes):
raise NotImplementedError(
Expand All @@ -76,6 +86,12 @@ def _notify_exercise_update(cls, exercise):
}
cls._notify_group(channel, event)

@classmethod
def _notify_action_check_update(cls, exercise):
channel = cls.get_live_group_name(exercise)
event = {"type": ChannelEventTypes.ACTION_CHECK_CHANGED_EVENT}
cls._notify_group(channel, event)


class ActionInstanceDispatcher(ChannelNotifier):
@classmethod
Expand Down Expand Up @@ -104,10 +120,7 @@ def _notify_action_event(cls, applied_action, event_type):
raise ValueError(
"ActionInstance must be associated with a patient_instance or lab."
)
if applied_action.patient_instance:
channel = cls.get_group_name(applied_action.patient_instance)
if applied_action.lab:
channel = cls.get_group_name(applied_action.lab)
channel = cls.get_group_name(applied_action.attached_instance())

event = {
"type": event_type,
Expand All @@ -125,13 +138,10 @@ def create_trainer_log(cls, applied_action, changes, is_updated):
message = f'"{applied_action.name}" wurde gestartet'
elif applied_action.state_name == models.ActionInstanceStateNames.FINISHED:
message = f'"{applied_action.name}" wurde abgeschlossen'
if (
applied_action.action_template.category
== template.Action.Category.PRODUCTION
):
if applied_action.template.category == template.Action.Category.PRODUCTION:
named_produced_resources = {
material.name: amount
for material, amount in applied_action.action_template.produced_resources().items()
for material, amount in applied_action.template.produced_resources().items()
}
message += f" und hat {str(named_produced_resources)} produziert"
elif (
Expand Down Expand Up @@ -166,18 +176,26 @@ def create_trainer_log(cls, applied_action, changes, is_updated):
log_entry.is_dirty = False
log_entry.save(update_fields=["is_dirty"])

@classmethod
def get_exercise(cls, applied_action):
return applied_action.exercise


class AreaDispatcher(ChannelNotifier):
@classmethod
def dispatch_event(cls, area, changes, is_updated):
cls._notify_exercise_update(area.exercise)
cls._notify_exercise_update(cls.get_exercise(area))

@classmethod
def delete_and_notify(cls, area, *args, **kwargs):
exercise = area.exercise
exercise = cls.get_exercise(area)
super(area.__class__, area).delete(*args, **kwargs)
cls._notify_exercise_update(exercise)

@classmethod
def get_exercise(cls, area):
return area.exercise


class ExerciseDispatcher(ChannelNotifier):
@classmethod
Expand All @@ -202,6 +220,10 @@ def create_trainer_log(cls, exercise, changes, is_updated):
if message:
models.LogEntry.objects.create(exercise=exercise, message=message)

@classmethod
def get_exercise(cls, exercise):
return exercise

@classmethod
def _notify_exercise_start_event(cls, exercise):
channel = cls.get_group_name(exercise)
Expand All @@ -215,25 +237,18 @@ def _notify_exercise_end_event(cls, exercise):
cls._notify_group(channel, event)


class MaterialInstanceDispatcher(ChannelNotifier):
@classmethod
def dispatch_event(cls, material, changes, is_updated):
cls._notify_exercise_update(material.attached_instance().exercise)

@classmethod
def delete_and_notify(cls, material, *args, **kwargs):
exercise = material.attached_instance().exercise
super(material.__class__, material).delete(*args, **kwargs)
cls._notify_exercise_update(exercise)


class LogEntryDispatcher(ChannelNotifier):
@classmethod
def get_group_name(cls, exercise):
return f"{exercise.__class__.__name__}_{exercise.id}_log"

@classmethod
def get_exercise(cls, log_entry):
return log_entry.exercise

@classmethod
def dispatch_event(cls, log_entry, changes, is_updated):

if log_entry.is_valid():
cls._notify_log_update_event(log_entry)

Expand All @@ -247,17 +262,33 @@ def _notify_log_update_event(cls, log_entry):
cls._notify_group(channel, event)


class MaterialInstanceDispatcher(ChannelNotifier):
@classmethod
def dispatch_event(cls, material, changes, is_updated):
cls._notify_exercise_update(material.attached_instance().exercise)

@classmethod
def delete_and_notify(cls, material, *args, **kwargs):
exercise = material.attached_instance().exercise
super(material.__class__, material).delete(*args, **kwargs)
cls._notify_exercise_update(exercise)

@classmethod
def get_exercise(cls, material):
return material.attached_instance().exercise


class PatientInstanceDispatcher(ChannelNotifier):

@classmethod
def dispatch_event(cls, patient_instance, changes, is_updated):
if changes is not None and "patient_state" in changes:
if changes and "patient_state" in changes:
cls._notify_patient_state_change(patient_instance)

if not (
changes is not None and len(changes) == 1 and "patient_state" in changes
):
cls._notify_exercise_update(patient_instance.exercise)
cls._notify_exercise_update(cls.get_exercise(patient_instance))

@classmethod
def create_trainer_log(cls, patient_instance, changes, is_updated):
Expand All @@ -269,15 +300,19 @@ def create_trainer_log(cls, patient_instance, changes, is_updated):
and patient_instance.static_information.injury
):
message += f" Patient*in hat folgende Verletzungen: {patient_instance.static_information.injury}"
elif "triage" in changes:
elif changes and "triage" in changes:
message = f"Patient*in {patient_instance.name} wurde triagiert auf {patient_instance.get_triage_display()}" # get_triage_display gets the long version of a ChoiceField
if message:
models.LogEntry.objects.create(
exercise=patient_instance.exercise,
exercise=cls.get_exercise(patient_instance),
message=message,
patient_instance=patient_instance,
)

@classmethod
def get_exercise(cls, patient_instance):
return patient_instance.exercise

@classmethod
def _notify_patient_state_change(cls, patient_instance):
channel = cls.get_group_name(patient_instance)
Expand All @@ -297,10 +332,14 @@ def delete_and_notify(cls, patient, *args, **kwargs):
class PersonnelDispatcher(ChannelNotifier):
@classmethod
def dispatch_event(cls, personnel, changes, is_updated):
cls._notify_exercise_update(personnel.area.exercise)
cls._notify_exercise_update(cls.get_exercise(personnel))

@classmethod
def delete_and_notify(cls, personnel, *args, **kwargs):
exercise = personnel.area.exercise
exercise = cls.get_exercise(personnel)
super(personnel.__class__, personnel).delete(*args, **kwargs)
cls._notify_exercise_update(exercise)

@classmethod
def get_exercise(cls, personnel):
return personnel.area.exercise
Loading

0 comments on commit 62e9557

Please sign in to comment.