Rehost world time state from calendar stepping
This commit is contained in:
parent
ef2c317b6b
commit
4623a05156
3 changed files with 182 additions and 1 deletions
|
|
@ -4133,6 +4133,45 @@ pub fn runtime_decode_packed_calendar_tuple(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn runtime_encode_packed_calendar_tuple(tuple: RuntimePackedCalendarTuple) -> (u32, u32) {
|
||||
let year_bytes = tuple.year_word.to_le_bytes();
|
||||
let word_0 = u32::from_le_bytes([
|
||||
year_bytes[0],
|
||||
year_bytes[1],
|
||||
tuple.month_1_based,
|
||||
tuple.week_1_based,
|
||||
]);
|
||||
let word_1 = u32::from_le_bytes([
|
||||
tuple.day_1_based,
|
||||
tuple.hour_0_based,
|
||||
tuple.quarter_day_1_based,
|
||||
tuple.minute_0_based,
|
||||
]);
|
||||
(word_0, word_1)
|
||||
}
|
||||
|
||||
pub fn runtime_derive_packed_calendar_tuple_from_calendar_point(
|
||||
calendar: CalendarPoint,
|
||||
) -> Option<RuntimePackedCalendarTuple> {
|
||||
let year_word = u16::try_from(calendar.year).ok()?;
|
||||
let month_1_based = u8::try_from(calendar.month_slot.checked_add(1)?).ok()?;
|
||||
let day_1_based = u8::try_from(calendar.phase_slot.checked_add(1)?).ok()?;
|
||||
let week_1_based = u8::try_from(calendar.phase_slot / 7 + 1).ok()?;
|
||||
let total_minutes = calendar.tick_slot.checked_mul(1440)? / crate::TICKS_PER_PHASE;
|
||||
let hour_0_based = u8::try_from(total_minutes / 60).ok()?;
|
||||
let minute_0_based = u8::try_from(total_minutes % 60).ok()?;
|
||||
let quarter_day_1_based = u8::try_from((u32::from(hour_0_based) / 6) + 1).ok()?;
|
||||
Some(RuntimePackedCalendarTuple {
|
||||
year_word,
|
||||
month_1_based,
|
||||
week_1_based,
|
||||
day_1_based,
|
||||
hour_0_based,
|
||||
quarter_day_1_based,
|
||||
minute_0_based,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn runtime_pack_packed_calendar_tuple_to_absolute_counter(
|
||||
tuple: RuntimePackedCalendarTuple,
|
||||
) -> Option<u32> {
|
||||
|
|
@ -7888,6 +7927,33 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derives_and_encodes_packed_calendar_tuple_from_runtime_calendar() {
|
||||
let tuple = runtime_derive_packed_calendar_tuple_from_calendar_point(CalendarPoint {
|
||||
year: 1830,
|
||||
month_slot: 11,
|
||||
phase_slot: 27,
|
||||
tick_slot: 179,
|
||||
})
|
||||
.expect("runtime calendar tuple");
|
||||
assert_eq!(
|
||||
tuple,
|
||||
RuntimePackedCalendarTuple {
|
||||
year_word: 1830,
|
||||
month_1_based: 12,
|
||||
week_1_based: 4,
|
||||
day_1_based: 28,
|
||||
hour_0_based: 23,
|
||||
quarter_day_1_based: 4,
|
||||
minute_0_based: 52,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
runtime_encode_packed_calendar_tuple(tuple),
|
||||
(0x040c_0726, 0x3404_171c)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derives_company_unassigned_share_pool_from_market_state_and_holdings() {
|
||||
let state = RuntimeState {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use crate::runtime::{
|
|||
runtime_round_f64_to_i64,
|
||||
};
|
||||
use crate::{
|
||||
RUNTIME_COMPANY_STAT_SLOT_COUNT, RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
|
||||
CalendarPoint, RUNTIME_COMPANY_STAT_SLOT_COUNT, RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
|
||||
RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN, RuntimeCargoClass, RuntimeCargoPriceTarget,
|
||||
RuntimeCargoProductionTarget, RuntimeChairmanMetric, RuntimeChairmanTarget,
|
||||
RuntimeCompanyControllerKind, RuntimeCompanyMetric, RuntimeCompanyTarget, RuntimeCondition,
|
||||
|
|
@ -191,6 +191,7 @@ fn step_once(
|
|||
boundary_events: &mut Vec<BoundaryEvent>,
|
||||
service_events: &mut Vec<ServiceEvent>,
|
||||
) -> Result<(), String> {
|
||||
let prior_calendar = state.calendar;
|
||||
let boundary = state.calendar.step_forward();
|
||||
if boundary != BoundaryEventKind::Tick {
|
||||
boundary_events.push(BoundaryEvent {
|
||||
|
|
@ -199,8 +200,10 @@ fn step_once(
|
|||
});
|
||||
}
|
||||
if boundary == BoundaryEventKind::YearRollover {
|
||||
service_sync_world_restore_time_from_calendar(state, prior_calendar);
|
||||
service_periodic_boundary(state, service_events)?;
|
||||
}
|
||||
service_sync_world_restore_time_from_calendar(state, state.calendar);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -213,6 +216,31 @@ fn boundary_kind_label(boundary: BoundaryEventKind) -> &'static str {
|
|||
}
|
||||
}
|
||||
|
||||
fn service_sync_world_restore_time_from_calendar(
|
||||
state: &mut RuntimeState,
|
||||
calendar: CalendarPoint,
|
||||
) {
|
||||
if let Ok(year_word) = u16::try_from(calendar.year) {
|
||||
state.world_restore.packed_year_word_raw_u16 = Some(year_word);
|
||||
}
|
||||
if let Ok(partial_year_progress) = u8::try_from(calendar.month_slot.saturating_add(1)) {
|
||||
state.world_restore.partial_year_progress_raw_u8 = Some(partial_year_progress);
|
||||
}
|
||||
if let Some(tuple) =
|
||||
crate::runtime::runtime_derive_packed_calendar_tuple_from_calendar_point(calendar)
|
||||
{
|
||||
let (word_0, word_1) = crate::runtime::runtime_encode_packed_calendar_tuple(tuple);
|
||||
state.world_restore.current_calendar_tuple_word_raw_u32 = Some(word_0);
|
||||
state.world_restore.current_calendar_tuple_word_2_raw_u32 = Some(word_1);
|
||||
if let Some(absolute_counter) =
|
||||
crate::runtime::runtime_pack_packed_calendar_tuple_to_absolute_counter(tuple)
|
||||
{
|
||||
state.world_restore.absolute_counter_raw_u32 = Some(absolute_counter);
|
||||
state.world_restore.absolute_counter_mirror_raw_u32 = Some(absolute_counter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn service_periodic_boundary(
|
||||
state: &mut RuntimeState,
|
||||
service_events: &mut Vec<ServiceEvent>,
|
||||
|
|
@ -2922,6 +2950,24 @@ mod tests {
|
|||
|
||||
assert_eq!(result.steps_executed, 5);
|
||||
assert_eq!(state.calendar.tick_slot, 5);
|
||||
assert_eq!(state.world_restore.packed_year_word_raw_u16, Some(1830));
|
||||
assert_eq!(state.world_restore.partial_year_progress_raw_u8, Some(1));
|
||||
assert_eq!(
|
||||
state.world_restore.current_calendar_tuple_word_raw_u32,
|
||||
Some(0x0101_0726)
|
||||
);
|
||||
assert_eq!(
|
||||
state.world_restore.current_calendar_tuple_word_2_raw_u32,
|
||||
Some(0x2801_0001)
|
||||
);
|
||||
assert_eq!(
|
||||
state.world_restore.absolute_counter_raw_u32,
|
||||
Some(885_427_240)
|
||||
);
|
||||
assert_eq!(
|
||||
state.world_restore.absolute_counter_mirror_raw_u32,
|
||||
Some(885_427_240)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -2974,6 +3020,24 @@ mod tests {
|
|||
.get("world.periodic_rollover_service_fired"),
|
||||
Some(&true)
|
||||
);
|
||||
assert_eq!(state.world_restore.packed_year_word_raw_u16, Some(1831));
|
||||
assert_eq!(state.world_restore.partial_year_progress_raw_u8, Some(1));
|
||||
assert_eq!(
|
||||
state.world_restore.current_calendar_tuple_word_raw_u32,
|
||||
Some(0x0101_0727)
|
||||
);
|
||||
assert_eq!(
|
||||
state.world_restore.current_calendar_tuple_word_2_raw_u32,
|
||||
Some(0x0001_0001)
|
||||
);
|
||||
assert_eq!(
|
||||
state.world_restore.absolute_counter_raw_u32,
|
||||
Some(885_911_040)
|
||||
);
|
||||
assert_eq!(
|
||||
state.world_restore.absolute_counter_mirror_raw_u32,
|
||||
Some(885_911_040)
|
||||
);
|
||||
assert!(
|
||||
result
|
||||
.service_events
|
||||
|
|
|
|||
51
docs/rehost-queue.md
Normal file
51
docs/rehost-queue.md
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# Rehost Queue
|
||||
|
||||
Working rule:
|
||||
|
||||
- Do not stop after commits.
|
||||
- After each commit, check this queue and continue.
|
||||
- Only stop if the queue is empty, you hit a real blocker, or you need approval.
|
||||
- Before any final response, state which stop condition is true. If none is true, continue.
|
||||
|
||||
## Next
|
||||
|
||||
- Rehost world time owner-state progression from `CalendarPoint` into `world_restore`:
|
||||
sync `packed_year_word_raw_u16`, `partial_year_progress_raw_u8`, packed calendar tuple words,
|
||||
and absolute counter so shellless stepping advances the same finance/economy reader inputs used
|
||||
by periodic service.
|
||||
- Make automatic year-rollover periodic service run against a consistent end-of-year world-time
|
||||
snapshot, then refresh into the new-year snapshot after service commits.
|
||||
- Rehost the next shellless periodic-boundary world work under
|
||||
`simulation_service_periodic_boundary_work`, starting with any bounded non-dialog queue/state
|
||||
family that can execute without shell ownership.
|
||||
|
||||
## In Progress
|
||||
|
||||
- Widen shellless simulation from explicit service commands toward “advance the runtime clock and
|
||||
the simulation-owned services advance with it.”
|
||||
|
||||
## Queued
|
||||
|
||||
- Rehost additional periodic finance/service branches that still depend on frozen world restore
|
||||
fields instead of advanced runtime-owned time state.
|
||||
- Reduce remaining company/chairman save-native gaps that still block standalone simulation
|
||||
quality, especially controller-kind closure and any deeper finance/state fields that still rely
|
||||
on conservative defaults.
|
||||
- Rehost bounded live economy owner state beyond selector/catalog/override surfaces when a
|
||||
concrete non-shell-owned seam is grounded.
|
||||
- Keep tightening shell-owned parity families only when that directly supports later rehosting.
|
||||
|
||||
## Blocked
|
||||
|
||||
- Full shell/dialog ownership remains intentionally out of scope.
|
||||
- Any candidate slice that requires guessing rather than rehosting owning state or real
|
||||
reader/setter families stays blocked until a better owner seam is grounded.
|
||||
|
||||
## Recently Done
|
||||
|
||||
- Automatic year-rollover calendar stepping now invokes periodic-boundary service.
|
||||
- Company cash, confiscation, and major governance effects now write through owner state instead of
|
||||
drifting from market/cache readers.
|
||||
- Company credit rating, prime rate, book value per share, investor confidence, and management
|
||||
attitude now refresh from grounded owner-state readers.
|
||||
- Annual finance service persists structured news events and grounded debt/share flow totals.
|
||||
Loading…
Add table
Add a link
Reference in a new issue