@@ -1121,14 +1121,18 @@ impl<K, V> MutableBTreeMap<K, V> {
11211121 let replay_lazy_signal = LazySignal :: new ( clone ! ( ( self => self_) move |world: & mut World | {
11221122 let broadcaster_system = world. get:: <MutableBTreeMapData <K , V >>( self_. entity) . unwrap( ) . broadcaster. clone( ) . register( world) ;
11231123
1124+ let was_initially_empty = self_. read( & * world) . is_empty( ) ;
1125+
11241126 let replay_entity = LazyEntity :: new( ) ;
11251127 let replay_system = clone!( ( self_, replay_entity) move |In ( upstream_diffs) : In <Vec <MapDiff <K , V >>>, replay_onces: Query <& ReplayOnce , Allow <Internal >>, mutable_btree_map_datas: Query <& MutableBTreeMapData <K , V >>| {
11261128 if replay_onces. contains( * replay_entity) {
1127- let initial_map = self_ . read ( & mutable_btree_map_datas ) ;
1128- if ! initial_map. is_empty ( ) {
1129+ if !was_initially_empty {
1130+ let initial_map = self_ . read ( & mutable_btree_map_datas ) ;
11291131 Some ( vec![ MapDiff :: Replace { entries: initial_map. iter( ) . map( |( k, v) | ( k. clone( ) , v. clone( ) ) ) . collect( ) } ] )
1130- } else {
1132+ } else if upstream_diffs . is_empty ( ) {
11311133 None
1134+ } else {
1135+ Some ( upstream_diffs)
11321136 }
11331137 } else if upstream_diffs. is_empty( ) { None } else { Some ( upstream_diffs) }
11341138 } ) ;
@@ -2172,4 +2176,111 @@ pub(crate) mod tests {
21722176
21732177 cleanup ( true ) ;
21742178 }
2179+
2180+ #[ test]
2181+ fn test_empty_map_first_insert ( ) {
2182+ {
2183+ // Test that when a MutableBTreeMap starts empty and we insert into it,
2184+ // we only get one Insert diff (not a duplicate with Replace)
2185+
2186+ let mut app = create_test_app ( ) ;
2187+ app. init_resource :: < SignalMapOutput < String , i32 > > ( ) ;
2188+
2189+ // Start with an empty map
2190+ let source_map = MutableBTreeMap :: from ( app. world_mut ( ) ) ;
2191+
2192+ // Create a signal_map and register it
2193+ let signal = source_map. signal_map ( ) ;
2194+ let handle = signal. for_each ( capture_map_output) . register ( app. world_mut ( ) ) ;
2195+
2196+ // Insert the first entry
2197+ source_map. write ( app. world_mut ( ) ) . insert ( "a" . to_string ( ) , 42 ) ;
2198+ app. update ( ) ;
2199+
2200+ // Should get exactly one Insert diff, not [Replace, Insert]
2201+ let diffs = get_and_clear_map_output :: < String , i32 > ( app. world_mut ( ) ) ;
2202+ assert_eq ! (
2203+ diffs. len( ) ,
2204+ 1 ,
2205+ "Expected exactly one diff for first insert to empty map"
2206+ ) ;
2207+ assert_eq ! (
2208+ diffs[ 0 ] ,
2209+ MapDiff :: Insert {
2210+ key: "a" . to_string( ) ,
2211+ value: 42
2212+ } ,
2213+ "Expected an Insert diff, not a Replace"
2214+ ) ;
2215+
2216+ // Insert another entry to verify normal operation continues
2217+ source_map. write ( app. world_mut ( ) ) . insert ( "b" . to_string ( ) , 99 ) ;
2218+ app. update ( ) ;
2219+
2220+ let diffs = get_and_clear_map_output :: < String , i32 > ( app. world_mut ( ) ) ;
2221+ assert_eq ! ( diffs. len( ) , 1 ) ;
2222+ assert_eq ! (
2223+ diffs[ 0 ] ,
2224+ MapDiff :: Insert {
2225+ key: "b" . to_string( ) ,
2226+ value: 99
2227+ }
2228+ ) ;
2229+
2230+ handle. cleanup ( app. world_mut ( ) ) ;
2231+ }
2232+
2233+ cleanup ( true ) ;
2234+ }
2235+
2236+ #[ test]
2237+ fn test_nonempty_map_initial_replace ( ) {
2238+ {
2239+ // Test that when a MutableBTreeMap starts with entries,
2240+ // we get an initial Replace diff
2241+
2242+ let mut app = create_test_app ( ) ;
2243+ app. init_resource :: < SignalMapOutput < String , i32 > > ( ) ;
2244+
2245+ // Start with a map containing initial entries
2246+ let source_map =
2247+ MutableBTreeMapBuilder :: from ( [ ( "x" . to_string ( ) , 1 ) , ( "y" . to_string ( ) , 2 ) , ( "z" . to_string ( ) , 3 ) ] )
2248+ . spawn ( app. world_mut ( ) ) ;
2249+
2250+ // Create a signal_map and register it
2251+ let signal = source_map. signal_map ( ) ;
2252+ let handle = signal. for_each ( capture_map_output) . register ( app. world_mut ( ) ) ;
2253+
2254+ // First update should produce a Replace with initial entries
2255+ app. update ( ) ;
2256+
2257+ let diffs = get_and_clear_map_output :: < String , i32 > ( app. world_mut ( ) ) ;
2258+ assert_eq ! ( diffs. len( ) , 1 , "Expected exactly one diff for initial state" ) ;
2259+ assert_eq ! (
2260+ diffs[ 0 ] ,
2261+ MapDiff :: Replace {
2262+ entries: vec![ ( "x" . to_string( ) , 1 ) , ( "y" . to_string( ) , 2 ) , ( "z" . to_string( ) , 3 ) , ]
2263+ } ,
2264+ "Expected a Replace diff with initial entries"
2265+ ) ;
2266+
2267+ // Insert another entry to verify normal operation continues
2268+ source_map. write ( app. world_mut ( ) ) . insert ( "w" . to_string ( ) , 4 ) ;
2269+ app. update ( ) ;
2270+
2271+ let diffs = get_and_clear_map_output :: < String , i32 > ( app. world_mut ( ) ) ;
2272+ assert_eq ! ( diffs. len( ) , 1 ) ;
2273+ assert_eq ! (
2274+ diffs[ 0 ] ,
2275+ MapDiff :: Insert {
2276+ key: "w" . to_string( ) ,
2277+ value: 4
2278+ }
2279+ ) ;
2280+
2281+ handle. cleanup ( app. world_mut ( ) ) ;
2282+ }
2283+
2284+ cleanup ( true ) ;
2285+ }
21752286}
0 commit comments