Fix Timeline::ApplyJsonDiff to make changes to our data first, and then clear cache afterwards (potential race condition)

This commit is contained in:
Jonathan Thomas
2025-06-07 16:03:55 -05:00
parent cdaccf2e90
commit 805af0dffc

View File

@@ -1412,13 +1412,6 @@ void Timeline::apply_json_to_clips(Json::Value change) {
}
}
// Calculate start and end frames that this impacts, and remove those frames from the cache
if (!change["value"].isArray() && !change["value"]["position"].isNull()) {
int64_t new_starting_frame = (change["value"]["position"].asDouble() * info.fps.ToDouble()) + 1;
int64_t new_ending_frame = ((change["value"]["position"].asDouble() + change["value"]["end"].asDouble() - change["value"]["start"].asDouble()) * info.fps.ToDouble()) + 1;
final_cache->Remove(new_starting_frame - 8, new_ending_frame + 8);
}
// Determine type of change operation
if (change_type == "insert") {
@@ -1438,6 +1431,8 @@ void Timeline::apply_json_to_clips(Json::Value change) {
// Update existing clip
if (existing_clip) {
// Update clip properties from JSON
existing_clip->SetJsonValue(change["value"]);
// Calculate start and end frames that this impacts, and remove those frames from the cache
int64_t old_starting_frame = (existing_clip->Position() * info.fps.ToDouble()) + 1;
@@ -1448,9 +1443,6 @@ void Timeline::apply_json_to_clips(Json::Value change) {
if (existing_clip->Reader() && existing_clip->Reader()->GetCache())
existing_clip->Reader()->GetCache()->Remove(old_starting_frame - 8, old_ending_frame + 8);
// Update clip properties from JSON
existing_clip->SetJsonValue(change["value"]);
// Apply framemapper (or update existing framemapper)
if (auto_map_clips) {
apply_mapper_to_clip(existing_clip);
@@ -1461,18 +1453,24 @@ void Timeline::apply_json_to_clips(Json::Value change) {
// Remove existing clip
if (existing_clip) {
// Remove clip from timeline
RemoveClip(existing_clip);
// Calculate start and end frames that this impacts, and remove those frames from the cache
int64_t old_starting_frame = (existing_clip->Position() * info.fps.ToDouble()) + 1;
int64_t old_ending_frame = ((existing_clip->Position() + existing_clip->Duration()) * info.fps.ToDouble()) + 1;
final_cache->Remove(old_starting_frame - 8, old_ending_frame + 8);
// Remove clip from timeline
RemoveClip(existing_clip);
}
}
// Calculate start and end frames that this impacts, and remove those frames from the cache
if (!change["value"].isArray() && !change["value"]["position"].isNull()) {
int64_t new_starting_frame = (change["value"]["position"].asDouble() * info.fps.ToDouble()) + 1;
int64_t new_ending_frame = ((change["value"]["position"].asDouble() + change["value"]["end"].asDouble() - change["value"]["start"].asDouble()) * info.fps.ToDouble()) + 1;
final_cache->Remove(new_starting_frame - 8, new_ending_frame + 8);
}
// Re-Sort Clips (since they likely changed)
sort_clips();
}