prediction: push the bulk of the main event loop into the session impl finally
This commit is contained in:
+68
-58
@@ -44,7 +44,8 @@ struct Session {
|
||||
scenery: Scenery,
|
||||
tokens_consumed: usize,
|
||||
activity_notify: watch::Sender<bool>,
|
||||
scene_sink: watch::Sender<Scene>
|
||||
scene_sink: watch::Sender<Scene>,
|
||||
do_regen: bool
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
|
||||
@@ -83,10 +84,70 @@ impl Session {
|
||||
direction,
|
||||
tokens_consumed: 0,
|
||||
activity_notify,
|
||||
scene_sink
|
||||
scene_sink,
|
||||
do_regen: false
|
||||
}
|
||||
}
|
||||
|
||||
async fn commit(&mut self) {
|
||||
let save_data = SaveData {
|
||||
direction: self.direction.clone(),
|
||||
messages: self.messages.clone(),
|
||||
scenery: self.scenery.clone()
|
||||
};
|
||||
|
||||
save_data.save();
|
||||
|
||||
if self.do_regen {
|
||||
self.regenerate_options().await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn on_event(&mut self, evt: PredictionAction) {
|
||||
self.do_regen = match evt {
|
||||
PredictionAction::ConversationAppend(msg) => {
|
||||
let do_regen = match msg {
|
||||
ConversationEntry::Eva(_) | ConversationEntry::ShipComputer(_) | ConversationEntry::User(_) => true,
|
||||
_ => false
|
||||
};
|
||||
self.insert_conversation(msg);
|
||||
|
||||
do_regen
|
||||
},
|
||||
PredictionAction::SetPlaylist(playlist_name) => {
|
||||
let args = MixxxQuery { playlist_name };
|
||||
match MixxxDB.query(&args).await {
|
||||
Err(err) => log::info!("Failed to load mixxx playlist: {:?}.", err),
|
||||
Ok(playlist) => {
|
||||
self.scenery.current_playlist = vec![];
|
||||
for item in playlist.clone() {
|
||||
if let Contents::Track(as_track) = item.contents() {
|
||||
self.scenery.current_playlist.push(as_track.clone());
|
||||
}
|
||||
self.scenery.artifacts.insert(item);
|
||||
}
|
||||
self.scenery.artifacts.synchronize().await;
|
||||
self.direction.playlist = args.playlist_name;
|
||||
log::info!("Mixxx playlist reloaded.");
|
||||
}
|
||||
}
|
||||
false
|
||||
},
|
||||
PredictionAction::GeneratePredictions => {
|
||||
true
|
||||
},
|
||||
PredictionAction::SetNarrative(narrative) => {
|
||||
self.direction.narrative = narrative;
|
||||
log::info!("Updated stage direction narrative");
|
||||
true
|
||||
},
|
||||
PredictionAction::SetShowEndTime(end_time) => {
|
||||
self.direction.end_time = end_time;
|
||||
false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async fn tool_stage_event(&mut self, args: StageEventArgs) -> ToolResults {
|
||||
let msg = match args.event {
|
||||
StageEvent::ShipComputer(text) => ConversationEntry::ShipComputer(text),
|
||||
@@ -139,6 +200,7 @@ impl Session {
|
||||
}
|
||||
|
||||
async fn regenerate_options(&mut self) {
|
||||
self.do_regen = false;
|
||||
self.reply_options.responses.clear();
|
||||
self.refresh();
|
||||
self.activity_notify.send_if_modified(|x| { if !*x { *x = true; true } else { false }});
|
||||
@@ -332,62 +394,10 @@ pub async fn start_prediction(saved_session: SaveData, mut messages: tokio::sync
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
if let Some(evt) = action_src.recv().await {
|
||||
let mut session = shared_session.write().await;
|
||||
let do_regen = match evt {
|
||||
PredictionAction::ConversationAppend(msg) => {
|
||||
let do_regen = match msg {
|
||||
ConversationEntry::Eva(_) | ConversationEntry::ShipComputer(_) | ConversationEntry::User(_) => true,
|
||||
_ => false
|
||||
};
|
||||
session.insert_conversation(msg);
|
||||
|
||||
do_regen
|
||||
},
|
||||
PredictionAction::SetPlaylist(playlist_name) => {
|
||||
let args = MixxxQuery { playlist_name };
|
||||
match MixxxDB.query(&args).await {
|
||||
Err(err) => log::info!("Failed to load mixxx playlist: {:?}.", err),
|
||||
Ok(playlist) => {
|
||||
session.scenery.current_playlist = vec![];
|
||||
for item in playlist.clone() {
|
||||
if let Contents::Track(as_track) = item.contents() {
|
||||
session.scenery.current_playlist.push(as_track.clone());
|
||||
}
|
||||
session.scenery.artifacts.insert(item);
|
||||
}
|
||||
session.scenery.artifacts.synchronize().await;
|
||||
session.direction.playlist = args.playlist_name;
|
||||
log::info!("Mixxx playlist reloaded.");
|
||||
}
|
||||
}
|
||||
false
|
||||
},
|
||||
PredictionAction::GeneratePredictions => {
|
||||
true
|
||||
},
|
||||
PredictionAction::SetNarrative(narrative) => {
|
||||
session.direction.narrative = narrative;
|
||||
log::info!("Updated stage direction narrative");
|
||||
true
|
||||
},
|
||||
PredictionAction::SetShowEndTime(end_time) => {
|
||||
session.direction.end_time = end_time;
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
let save_data = SaveData {
|
||||
direction: session.direction.clone(),
|
||||
messages: session.messages.clone(),
|
||||
scenery: session.scenery.clone()
|
||||
};
|
||||
|
||||
save_data.save();
|
||||
|
||||
if do_regen {
|
||||
drop(session);
|
||||
shared_session.write().await.regenerate_options().await;
|
||||
}
|
||||
shared_session.write().await.on_event(evt).await;
|
||||
// Commit in a separate unlock operation, so the logging task has time to write messages into the conversation
|
||||
// FIXME: The conversation we see in the UI really needs to go to another task.
|
||||
shared_session.write().await.commit().await;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user