mirror of
https://github.com/aclist/dztui.git
synced 2026-10-25 12:12:31 +01:00
change: simplify calculation logic
This commit is contained in:
1 parent
ac286f4a72
commit
cb5c233f45
1 file changed
+53
-100
+53
-100
@@ -44,6 +44,10 @@ class Emitter(GObject.GObject):
|
|||||||
def target_time_changed(self, time: timedelta) -> None:
|
def target_time_changed(self, time: timedelta) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=(object,))
|
||||||
|
def target_time_reset(self, time: timedelta) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=(object,))
|
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=(object,))
|
||||||
def remaining_time_changed(self, time: datetime) -> None:
|
def remaining_time_changed(self, time: datetime) -> None:
|
||||||
pass
|
pass
|
||||||
@@ -87,38 +91,24 @@ class ServerClock:
|
|||||||
self.start_time = datetime.combine(datetime.today(), time(hour, minute))
|
self.start_time = datetime.combine(datetime.today(), time(hour, minute))
|
||||||
self.cur_time = datetime.combine(datetime.today(), time(hour, minute))
|
self.cur_time = datetime.combine(datetime.today(), time(hour, minute))
|
||||||
|
|
||||||
# NOTE: at highest possible accel interval (64 * 64), real time is 0.876 seconds
|
# NOTE: highest theoretical accel interval is 24 * 64 at night
|
||||||
if self.is_night():
|
GLib.timeout_add(400, self._increment_with_offset)
|
||||||
GLib.timeout_add(500, self.increment_night)
|
|
||||||
else:
|
|
||||||
GLib.timeout_add(500, self.increment_day)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def split_time(server_time: Time) -> tuple[int, int]:
|
def split_time(server_time: Time) -> tuple[int, int]:
|
||||||
split = server_time.time.split(":")
|
split = server_time.time.split(":")
|
||||||
return int(split[0]), int(split[1])
|
return int(split[0]), int(split[1])
|
||||||
|
|
||||||
def _increment_with_offset(self, offset: float) -> None:
|
def _increment_with_offset(self) -> None:
|
||||||
|
factor = self.get_accel_factor(self.cur_time)
|
||||||
elapsed = self.local_clock.get_elapsed_time()
|
elapsed = self.local_clock.get_elapsed_time()
|
||||||
virtual_elapsed = elapsed * offset
|
virtual_elapsed = elapsed * factor
|
||||||
self.cur_time = self.start_time + virtual_elapsed
|
self.cur_time = self.start_time + virtual_elapsed
|
||||||
self.emitter.emit("server_time_incremented", self.cur_time)
|
self.emitter.emit("server_time_incremented", self.cur_time)
|
||||||
|
|
||||||
def increment_day(self) -> bool:
|
|
||||||
if self.is_night():
|
|
||||||
GLib.timeout_add(500, self.increment_night)
|
|
||||||
return False
|
|
||||||
offset = self.day_accel
|
|
||||||
self._increment_with_offset(offset)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def increment_night(self) -> bool:
|
def increment(self) -> bool:
|
||||||
if not self.is_night():
|
self._increment_with_offset
|
||||||
GLib.timeout_add(500, self.increment_day)
|
|
||||||
return False
|
|
||||||
offset = self.night_accel * self.day_accel
|
|
||||||
self._increment_with_offset(offset)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def is_night(self) -> bool:
|
def is_night(self) -> bool:
|
||||||
return (
|
return (
|
||||||
@@ -126,92 +116,47 @@ class ServerClock:
|
|||||||
or self.cur_time.time() <= NIGHT_END_TIME
|
or self.cur_time.time() <= NIGHT_END_TIME
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_accel_factor(self, dt: datetime) -> bool:
|
||||||
|
return (
|
||||||
|
self.day_accel
|
||||||
|
if DAY_START_TIME <= dt.time() < DAY_END_TIME
|
||||||
|
else (self.night_accel * self.day_accel)
|
||||||
|
)
|
||||||
|
|
||||||
def get_values(self) -> tuple[int, int]:
|
def get_values(self) -> tuple[int, int]:
|
||||||
return self.cur_time.hour, self.cur_time.minute
|
return self.cur_time.hour, self.cur_time.minute
|
||||||
|
|
||||||
def get_time(self) -> time:
|
def get_time(self) -> time:
|
||||||
return self.cur_time.time()
|
return self.cur_time.time()
|
||||||
|
|
||||||
def get_cycle_remainder(self, accel: bool = True) -> float:
|
def calc_delta(self, end_time: datetime) -> timedelta:
|
||||||
# NOTE: calc from cycle start time to current point
|
total = 0.0
|
||||||
if self.is_night():
|
current_time = self.cur_time
|
||||||
cutoff = DAY_START_TIME
|
|
||||||
offset = self.day_accel * self.night_accel
|
|
||||||
else:
|
|
||||||
cutoff = NIGHT_START_TIME
|
|
||||||
offset = self.day_accel
|
|
||||||
start = datetime.combine(self.cur_time, cutoff)
|
|
||||||
|
|
||||||
if accel is False:
|
if current_time > end_time:
|
||||||
offset = 1
|
end_time += timedelta(days=1)
|
||||||
return (start - self.cur_time).total_seconds() / offset
|
while current_time < end_time:
|
||||||
|
factor = self.get_accel_factor(current_time)
|
||||||
|
|
||||||
def get_full_cycle(self, end_time: time, start_time: time) -> float:
|
edge = (
|
||||||
end = datetime.combine(self.cur_time, end_time)
|
DAY_END_TIME if current_time.time() < DAY_END_TIME else DAY_START_TIME
|
||||||
start = datetime.combine(self.cur_time, start_time)
|
)
|
||||||
if start > end:
|
|
||||||
end += timedelta(days=1)
|
|
||||||
return (end - start).total_seconds()
|
|
||||||
|
|
||||||
def get_day_cycle(self) -> float:
|
next_edge = datetime.combine(current_time.date(), edge)
|
||||||
return self.get_full_cycle(DAY_END_TIME, DAY_START_TIME)
|
|
||||||
|
|
||||||
def get_night_cycle(self) -> float:
|
if next_edge <= current_time:
|
||||||
return self.get_full_cycle(NIGHT_END_TIME, NIGHT_START_TIME)
|
next_edge += timedelta(days=1)
|
||||||
|
chunk_end = min(end_time, next_edge)
|
||||||
def get_delta(self, picker_time: time, start_time: time) -> float:
|
total += (chunk_end - current_time).total_seconds() / factor
|
||||||
start = datetime.combine(self.cur_time, start_time)
|
current_time = chunk_end
|
||||||
picker_date = datetime.combine(self.cur_time, picker_time)
|
return timedelta(seconds=total)
|
||||||
if start > picker_date:
|
|
||||||
picker_date += timedelta(days=1)
|
|
||||||
delta = (picker_date - start).total_seconds()
|
|
||||||
return delta
|
|
||||||
|
|
||||||
def get_next_cycle(self) -> float:
|
|
||||||
if self.is_night():
|
|
||||||
return self.get_day_cycle() / self.day_accel
|
|
||||||
else:
|
|
||||||
return self.get_night_cycle() / (self.day_accel * self.night_accel)
|
|
||||||
|
|
||||||
def get_remaining_delta(self, picker_time: time, is_night: bool) -> float:
|
|
||||||
if is_night:
|
|
||||||
start_time = NIGHT_START_TIME
|
|
||||||
offset = self.day_accel * self.night_accel
|
|
||||||
else:
|
|
||||||
start_time = DAY_START_TIME
|
|
||||||
offset = self.day_accel
|
|
||||||
return self.get_delta(picker_time, start_time) / offset
|
|
||||||
|
|
||||||
def calc_delta(self, picker_time: time, is_night: bool) -> timedelta:
|
|
||||||
# NOTE: time spans two full cycles
|
|
||||||
if self.get_time() > picker_time:
|
|
||||||
to_end = self.get_cycle_remainder()
|
|
||||||
next_cycle = self.get_next_cycle()
|
|
||||||
delta = self.get_remaining_delta(picker_time, is_night)
|
|
||||||
total = to_end + next_cycle + delta
|
|
||||||
else:
|
|
||||||
picker_date = datetime.combine(self.cur_time, picker_time)
|
|
||||||
# NOTE: strip sub-minute values
|
|
||||||
new = self.cur_time.replace(second=0, microsecond=0)
|
|
||||||
delta = (picker_date - new).total_seconds()
|
|
||||||
remainder_till_cycle_end = self.get_cycle_remainder(accel=False)
|
|
||||||
if delta <= remainder_till_cycle_end:
|
|
||||||
if self.is_night():
|
|
||||||
total = delta / (self.day_accel * self.night_accel)
|
|
||||||
else:
|
|
||||||
total = delta / self.day_accel
|
|
||||||
else:
|
|
||||||
total = self.get_remaining_delta(picker_time, is_night)
|
|
||||||
|
|
||||||
total = round(total)
|
|
||||||
td = timedelta(seconds=total)
|
|
||||||
return td
|
|
||||||
|
|
||||||
|
|
||||||
class RemainderClock:
|
class RemainderClock:
|
||||||
def __init__(self, emitter: Emitter) -> None:
|
def __init__(self, emitter: Emitter) -> None:
|
||||||
self.emitter = emitter
|
self.emitter = emitter
|
||||||
self.emitter.connect("target_time_changed", self._on_target_time_changed)
|
self.emitter.connect("target_time_changed", self._on_target_time_changed)
|
||||||
|
self.emitter.connect("target_time_reset", self._on_target_time_reset)
|
||||||
self.emitter.connect("local_time_incremented", self._on_local_time_incremented)
|
self.emitter.connect("local_time_incremented", self._on_local_time_incremented)
|
||||||
self.reset_time(True)
|
self.reset_time(True)
|
||||||
|
|
||||||
@@ -238,8 +183,12 @@ class RemainderClock:
|
|||||||
self.previous = elapsed
|
self.previous = elapsed
|
||||||
self.emitter.emit("remaining_time_changed", self.time)
|
self.emitter.emit("remaining_time_changed", self.time)
|
||||||
|
|
||||||
|
def _on_target_time_reset(self, emitter: Emitter, time: timedelta) -> None:
|
||||||
|
self.reset_time(True)
|
||||||
|
self.emitter.emit("remaining_time_changed", self.time)
|
||||||
|
|
||||||
def _on_target_time_changed(self, emitter: Emitter, time: timedelta) -> None:
|
def _on_target_time_changed(self, emitter: Emitter, time: timedelta) -> None:
|
||||||
self.reset_time()
|
self.reset_time(True)
|
||||||
self.time += time
|
self.time += time
|
||||||
self.emitter.emit("remaining_time_changed", self.time)
|
self.emitter.emit("remaining_time_changed", self.time)
|
||||||
|
|
||||||
@@ -323,11 +272,14 @@ class TimePicker(Gtk.Box):
|
|||||||
|
|
||||||
def get_time(self) -> time:
|
def get_time(self) -> time:
|
||||||
d = datetime.now()
|
d = datetime.now()
|
||||||
return time(
|
return datetime.combine(
|
||||||
hour=self.get_hour(),
|
d,
|
||||||
minute=self.get_minute(),
|
time(
|
||||||
second=d.second,
|
hour=self.get_hour(),
|
||||||
microsecond=d.microsecond,
|
minute=self.get_minute(),
|
||||||
|
second=d.second,
|
||||||
|
microsecond=d.microsecond,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def set_time(self, hour: int, minute: int) -> None:
|
def set_time(self, hour: int, minute: int) -> None:
|
||||||
@@ -448,11 +400,12 @@ class TimePickerFrame(Gtk.Frame):
|
|||||||
def _on_calculate_button_clicked(self, button: Gtk.Button) -> None:
|
def _on_calculate_button_clicked(self, button: Gtk.Button) -> None:
|
||||||
if (self.picker.get_values()) == (self.server_time.get_values()):
|
if (self.picker.get_values()) == (self.server_time.get_values()):
|
||||||
total_time = timedelta(seconds=0)
|
total_time = timedelta(seconds=0)
|
||||||
|
self.emitter.emit("target_time_reset", total_time)
|
||||||
else:
|
else:
|
||||||
picker_time = self.picker.get_time()
|
picker_time = self.picker.get_time()
|
||||||
is_night = self.picker.is_night()
|
total_time = self.server_time.calc_delta(picker_time)
|
||||||
total_time = self.server_time.calc_delta(picker_time, is_night)
|
print(total_time)
|
||||||
self.emitter.emit("target_time_changed", total_time)
|
self.emitter.emit("target_time_changed", total_time)
|
||||||
|
|
||||||
|
|
||||||
class ServerTimeCalculator(Gtk.ScrolledWindow):
|
class ServerTimeCalculator(Gtk.ScrolledWindow):
|
||||||
|
|||||||
Reference in new issue
Block a user