@@ -416,8 +416,14 @@ def parse_game_metadata(self) -> GameMetadata:
416416 all_logs = all_logs ,
417417 )
418418
419- def parse_trajectory (self , player_name : str , round_num : int ) -> TrajectoryInfo | None :
420- """Parse a specific trajectory file"""
419+ def parse_trajectory (self , player_name : str , round_num : int , * , load_diffs : bool = False ) -> TrajectoryInfo | None :
420+ """Parse a specific trajectory file
421+
422+ Args:
423+ player_name: Name of the player
424+ round_num: Round number
425+ load_diffs: If True, load diff data. If False (default), skip loading diffs for performance
426+ """
421427 player_dir = self .log_dir / "players" / player_name
422428 if not player_dir .exists ():
423429 return None
@@ -430,25 +436,28 @@ def parse_trajectory(self, player_name: str, round_num: int) -> TrajectoryInfo |
430436 info = data .get ("info" , {})
431437 model_stats = info .get ("model_stats" , {})
432438
433- # Get diff data from changes file
439+ # Get diff data from changes file only if requested
434440 diff = incremental_diff = modified_files = None
435- changes_file = player_dir / f"changes_r{ round_num } .json"
436- if changes_file .exists ():
437- try :
438- changes_data = json .loads (changes_file .read_text ())
439- diff = changes_data .get ("full_diff" , "" )
440- incremental_diff = changes_data .get ("incremental_diff" , "" )
441- modified_files = changes_data .get ("modified_files" , {})
442- except (json .JSONDecodeError , KeyError ):
443- pass
444-
445- # Filter and split diffs by files
446- filtered_diff = filter_git_diff (diff ) if diff else ""
447- filtered_incremental_diff = filter_git_diff (incremental_diff ) if incremental_diff else ""
448- diff_by_files = split_git_diff_by_files (filtered_diff ) if filtered_diff else {}
449- incremental_diff_by_files = (
450- split_git_diff_by_files (filtered_incremental_diff ) if filtered_incremental_diff else {}
451- )
441+ diff_by_files = incremental_diff_by_files = None
442+
443+ if load_diffs :
444+ changes_file = player_dir / f"changes_r{ round_num } .json"
445+ if changes_file .exists ():
446+ try :
447+ changes_data = json .loads (changes_file .read_text ())
448+ diff = changes_data .get ("full_diff" , "" )
449+ incremental_diff = changes_data .get ("incremental_diff" , "" )
450+ modified_files = changes_data .get ("modified_files" , {})
451+
452+ # Filter and split diffs by files
453+ filtered_diff = filter_git_diff (diff ) if diff else ""
454+ filtered_incremental_diff = filter_git_diff (incremental_diff ) if incremental_diff else ""
455+ diff_by_files = split_git_diff_by_files (filtered_diff ) if filtered_diff else {}
456+ incremental_diff_by_files = (
457+ split_git_diff_by_files (filtered_incremental_diff ) if filtered_incremental_diff else {}
458+ )
459+ except (json .JSONDecodeError , KeyError ):
460+ pass
452461
453462 return TrajectoryInfo (
454463 player_id = player_name ,
@@ -792,17 +801,16 @@ def render_game_viewer(folder_path: Path, selected_folder: str) -> str:
792801 parser = LogParser (folder_path )
793802 metadata = parser .parse_game_metadata ()
794803
795- # Group trajectories by round
804+ # Group trajectories by round (without loading diffs)
796805 trajectories_by_round = {}
797806 for player_name , round_num in parser .get_available_trajectories ():
798807 if round_num not in trajectories_by_round :
799808 trajectories_by_round [round_num ] = []
800- trajectory = parser .parse_trajectory (player_name , round_num )
809+ trajectory = parser .parse_trajectory (player_name , round_num , load_diffs = False )
801810 if trajectory :
802811 trajectories_by_round [round_num ].append (trajectory )
803812
804- # Get analysis data
805- analysis_data = parser .analyze_line_counts ()
813+ # Get analysis data (skip line counting - will be loaded on demand)
806814 sim_wins_data = parser .analyze_sim_wins_per_round ()
807815 matrix_data = parser .load_matrix_analysis ()
808816
@@ -815,7 +823,6 @@ def render_game_viewer(folder_path: Path, selected_folder: str) -> str:
815823 selected_folder_path = str (folder_path ),
816824 metadata = metadata ,
817825 trajectories_by_round = trajectories_by_round ,
818- analysis_data = analysis_data ,
819826 sim_wins_data = sim_wins_data ,
820827 matrix_data = matrix_data ,
821828 navigation = navigation_info ,
@@ -1244,4 +1251,48 @@ def load_log():
12441251 return jsonify ({"success" : False , "error" : f"Error reading file: { str (e )} " }), 500
12451252
12461253
1254+ @app .route ("/load-trajectory-diffs" )
1255+ def load_trajectory_diffs ():
1256+ """Load trajectory diff data on demand"""
1257+ selected_folder = request .args .get ("folder" )
1258+ player_name = request .args .get ("player" )
1259+ round_num = request .args .get ("round" )
1260+
1261+ if not all ([selected_folder , player_name , round_num ]):
1262+ return jsonify ({"success" : False , "error" : "Missing required parameters" }), 400
1263+
1264+ try :
1265+ round_num = int (round_num )
1266+ except ValueError :
1267+ return jsonify ({"success" : False , "error" : "Invalid round number" }), 400
1268+
1269+ try :
1270+ # Validate the selected folder exists and is a game folder
1271+ folder_path = LOG_BASE_DIR / selected_folder
1272+ if not folder_path .exists () or not is_game_folder (folder_path ):
1273+ return jsonify ({"success" : False , "error" : "Invalid game folder" }), 404
1274+
1275+ # Parse trajectory with diffs loaded
1276+ parser = LogParser (folder_path )
1277+ trajectory = parser .parse_trajectory (player_name , round_num , load_diffs = True )
1278+
1279+ if not trajectory :
1280+ return jsonify ({"success" : False , "error" : "Trajectory not found" }), 404
1281+
1282+ return jsonify (
1283+ {
1284+ "success" : True ,
1285+ "diff" : trajectory .diff ,
1286+ "incremental_diff" : trajectory .incremental_diff ,
1287+ "modified_files" : trajectory .modified_files ,
1288+ "diff_by_files" : trajectory .diff_by_files ,
1289+ "incremental_diff_by_files" : trajectory .incremental_diff_by_files ,
1290+ }
1291+ )
1292+
1293+ except Exception as e :
1294+ logger .error (f"Error loading trajectory diffs: { e } " , exc_info = True )
1295+ return jsonify ({"success" : False , "error" : str (e )}), 500
1296+
1297+
12471298# Use run_viewer.py to launch the application
0 commit comments