@@ -530,9 +530,14 @@ void flecs_table_emit(
530530 ecs_table_t * table ,
531531 ecs_entity_t event )
532532{
533+ ecs_type_t * ids = & table -> type ;
534+ if (table -> _ -> extended_type ) {
535+ ids = table -> _ -> extended_type ;
536+ }
537+
533538 ecs_defer_begin (world );
534539 flecs_emit (world , world , & (ecs_event_desc_t ) {
535- .ids = & table -> type ,
540+ .ids = ids ,
536541 .event = event ,
537542 .table = table ,
538543 .flags = EcsEventTableOnly ,
@@ -548,7 +553,8 @@ bool flecs_table_register_inherited_for_base(
548553 int32_t type_index ,
549554 int16_t column ,
550555 ecs_id_t base_id ,
551- ecs_vec_t * inherited )
556+ ecs_vec_t * inherited ,
557+ ecs_vec_t * inherited_wild )
552558{
553559 ecs_component_record_t * cr = flecs_components_ensure (world , base_id );
554560
@@ -576,7 +582,8 @@ bool flecs_table_register_inherited_for_base(
576582 ecs_table_cache_insert (& cr -> cache , table , & tr -> hdr );
577583 flecs_component_claim (world , cr );
578584
579- * ecs_vec_append_t (& world -> allocator , inherited , ecs_table_record_t * ) = tr ;
585+ ecs_vec_t * dst = ecs_id_is_wildcard (base_id ) ? inherited_wild : inherited ;
586+ * ecs_vec_append_t (& world -> allocator , dst , ecs_table_record_t * ) = tr ;
580587
581588 if (base_id < FLECS_HI_COMPONENT_ID ) {
582589 world -> non_trivial_lookup [base_id ] |= EcsNonTrivialIdInherit ;
@@ -593,7 +600,8 @@ void flecs_table_register_inherited_bases(
593600 int16_t column ,
594601 ecs_entity_t rel ,
595602 ecs_entity_t tgt ,
596- ecs_vec_t * inherited )
603+ ecs_vec_t * inherited ,
604+ ecs_vec_t * inherited_wild )
597605{
598606 ecs_record_t * r = flecs_entities_get (world , rel );
599607 if (!r ) {
@@ -621,19 +629,21 @@ void flecs_table_register_inherited_bases(
621629
622630 ecs_id_t base_id = tgt ? ecs_pair (base , tgt ) : base ;
623631 bool recurse = flecs_table_register_inherited_for_base (
624- world , table , type_index , column , base_id , inherited );
632+ world , table , type_index , column , base_id , inherited ,
633+ inherited_wild );
625634
626635 if (tgt ) {
627636 if (flecs_table_register_inherited_for_base (world , table ,
628- type_index , column , ecs_pair (base , EcsWildcard ), inherited ))
637+ type_index , column , ecs_pair (base , EcsWildcard ), inherited ,
638+ inherited_wild ))
629639 {
630640 recurse = true;
631641 }
632642 }
633643
634644 if (recurse ) {
635645 flecs_table_register_inherited_bases (world , table , type_index ,
636- column , base , tgt , inherited );
646+ column , base , tgt , inherited , inherited_wild );
637647 }
638648 }
639649}
@@ -648,8 +658,9 @@ void flecs_table_register_inherited(
648658 return ;
649659 }
650660
651- ecs_vec_t inherited ;
661+ ecs_vec_t inherited , inherited_wild ;
652662 ecs_vec_init_t (& world -> allocator , & inherited , ecs_table_record_t * , 0 );
663+ ecs_vec_init_t (& world -> allocator , & inherited_wild , ecs_table_record_t * , 0 );
653664
654665 ecs_type_t type = table -> type ;
655666 int32_t ti , count = type .count ;
@@ -670,21 +681,42 @@ void flecs_table_register_inherited(
670681
671682 int16_t column = table -> _ -> records [ti ].column ;
672683 flecs_table_register_inherited_bases (
673- world , table , ti , column , rel , tgt , & inherited );
684+ world , table , ti , column , rel , tgt , & inherited , & inherited_wild );
674685 }
675686
676- int32_t n = ecs_vec_count (& inherited );
687+ int32_t nw = ecs_vec_count (& inherited );
688+ int32_t ww = ecs_vec_count (& inherited_wild );
689+ int32_t n = nw + ww ;
677690 if (n ) {
678- int32_t i , old = table -> _ -> record_count ;
691+ /* Inherited records are inserted right after the table's own id records
692+ * so that the wildcard records remain at the end. Non-wildcard
693+ * inherited records (the base component ids) are placed first, followed
694+ * by the existing wildcard records and the inherited wildcard records.
695+ * This ensures the extended_type array (component ids + base ids)
696+ * mirrors the order of the records array and excludes wildcards. */
697+ int32_t i , type_count = type .count ;
698+ int32_t old = table -> _ -> record_count ;
699+ int32_t aux = old - type_count ;
679700 ecs_table_record_t * old_records = table -> _ -> records ;
680701 ecs_table_record_t * records = flecs_walloc_n (
681702 world , ecs_table_record_t , old + n );
682- ecs_os_memcpy_n (records , old_records , ecs_table_record_t , old );
683703
684- ecs_table_record_t * * inherited_records = ecs_vec_first_t (
704+ ecs_table_record_t * * nw_records = ecs_vec_first_t (
685705 & inherited , ecs_table_record_t * );
686- for (i = 0 ; i < n ; i ++ ) {
687- records [old + i ] = * inherited_records [i ];
706+ ecs_table_record_t * * ww_records = ecs_vec_first_t (
707+ & inherited_wild , ecs_table_record_t * );
708+
709+ ecs_os_memcpy_n (records , old_records , ecs_table_record_t , type_count );
710+
711+ for (i = 0 ; i < nw ; i ++ ) {
712+ records [type_count + i ] = * nw_records [i ];
713+ }
714+
715+ ecs_os_memcpy_n (& records [type_count + nw ], & old_records [type_count ],
716+ ecs_table_record_t , aux );
717+
718+ for (i = 0 ; i < ww ; i ++ ) {
719+ records [type_count + nw + aux + i ] = * ww_records [i ];
688720 }
689721
690722 table -> _ -> records = records ;
@@ -693,16 +725,44 @@ void flecs_table_register_inherited(
693725 for (i = 0 ; i < old + n ; i ++ ) {
694726 ecs_table_record_t * tr = & records [i ];
695727 ecs_table_cache_replace (& tr -> hdr .cr -> cache , table , & tr -> hdr );
728+
729+ /* Propagate table event flags for inherited base components, so
730+ * that OnTableCreate/OnTableDelete events are emitted for tables
731+ * with derived components (used to notify query caches). */
732+ table -> flags |= tr -> hdr .cr -> flags &
733+ (EcsIdHasOnTableCreate | EcsIdHasOnTableDelete );
734+ }
735+
736+ /* Build extended type with component ids + non-wildcard base ids */
737+ if (nw ) {
738+ int32_t et_count = type_count + nw ;
739+ ecs_type_t * et = flecs_walloc_t (world , ecs_type_t );
740+ et -> count = et_count ;
741+ et -> array = flecs_walloc_n (world , ecs_id_t , et_count );
742+ for (i = 0 ; i < type_count ; i ++ ) {
743+ et -> array [i ] = type .array [i ];
744+ }
745+ for (i = 0 ; i < nw ; i ++ ) {
746+ ecs_id_t base_id = records [type_count + i ].hdr .cr -> id ;
747+ et -> array [type_count + i ] = base_id ;
748+ table -> bloom_filter = flecs_table_bloom_filter_add (
749+ table -> bloom_filter , base_id );
750+ }
751+ table -> _ -> extended_type = et ;
696752 }
697753
698- for (i = 0 ; i < n ; i ++ ) {
699- flecs_wfree_t (world , ecs_table_record_t , inherited_records [i ]);
754+ for (i = 0 ; i < nw ; i ++ ) {
755+ flecs_wfree_t (world , ecs_table_record_t , nw_records [i ]);
756+ }
757+ for (i = 0 ; i < ww ; i ++ ) {
758+ flecs_wfree_t (world , ecs_table_record_t , ww_records [i ]);
700759 }
701760
702761 flecs_wfree_n (world , ecs_table_record_t , old , old_records );
703762 }
704763
705764 ecs_vec_fini_t (& world -> allocator , & inherited , ecs_table_record_t * );
765+ ecs_vec_fini_t (& world -> allocator , & inherited_wild , ecs_table_record_t * );
706766}
707767
708768/* Main table initialization function */
@@ -1479,6 +1539,12 @@ void flecs_table_fini(
14791539 ecs_os_free (table -> component_map );
14801540 flecs_table_records_unregister (world , table );
14811541
1542+ if (table -> _ -> extended_type ) {
1543+ flecs_wfree_n (world , ecs_id_t , table -> _ -> extended_type -> count ,
1544+ table -> _ -> extended_type -> array );
1545+ flecs_wfree_t (world , ecs_type_t , table -> _ -> extended_type );
1546+ }
1547+
14821548 /* Update counters */
14831549 world -> info .table_count -- ;
14841550 world -> info .table_delete_total ++ ;
0 commit comments