int match_function_component(bool eqconnection, struct endp f, struct endp c, endp amatch) { const char *ifname; void *ifentry; int matched = 0; env_scanner scanifs; bool want_defined; assert(f.function && !c.interface && !c.function); want_defined = f.function->defined ^ !eqconnection; component_scan(c.component, &scanifs); while (env_next(&scanifs, &ifname, &ifentry)) { data_declaration idecl = ifentry; c.function = c.interface = NULL; if (idecl->kind == decl_interface_ref) { c.interface = idecl; matched += match_function_interface(want_defined ^ idecl->required, f, c, amatch); } else { c.function = idecl; if (c.function->defined == want_defined) matched += match_endpoints(&f, &c, amatch); } } return matched; }
int match_function_interface(bool eqconnection, struct endp f, struct endp i, endp amatch) { #ifdef NO_FUNCTION_INTERFACE_MATCHING return 0; #else env_scanner scanfns; const char *fnname; void *fnentry; int matched = 0; bool want_defined; assert(f.function && !i.function); want_defined = f.function->defined ^ !eqconnection; /* Check all functions */ interface_scan(i.interface, &scanfns); while (env_next(&scanfns, &fnname, &fnentry)) { i.function = fnentry; if (i.function->defined == want_defined) matched += match_endpoints(&f, &i, amatch); } return matched; #endif }
int match_interface_component(bool eqconnection, struct endp i, struct endp c, endp amatch) { const char *ifname; void *ifentry; int matched = 0; env_scanner scanifs; bool want_required; assert(i.interface && !c.interface); want_required = i.interface->required ^ !eqconnection; component_scan(c.component, &scanifs); while (env_next(&scanifs, &ifname, &ifentry)) { data_declaration idecl = ifentry; if (idecl->kind == decl_interface_ref) { c.interface = idecl; if (c.interface->required == want_required) matched += match_endpoints(&i, &c, amatch); } } return matched; }
Nested<T> join_fragments_helper(const Nested<T>& fragments) { // Build array of endpoints Array<Vec2> X; for(const auto& f : fragments) { assert(!f.empty()); X.append(get_endpoint(f.front())); X.append(get_endpoint(f.back())); } Array<Match> current_matches = match_endpoints(X); // At this point each element in current_matches should have the join to the next fragment // We need to walk these matches and build a single nested array for the result // We build fragments by directly appending to the flat array, and update the offset array once the fragment is complete Nested<T,false> result; for(const int seed_match : range(current_matches.size())) { int curr = seed_match; while(current_matches[curr].is_set()) { const bool reversed = (curr & 1) != 0; // Even ids are starts of fragments, odd ids are ends of fragments add_fragment(result, fragments[curr>>1], reversed); const int next = current_matches[curr^1].end; // Next fragment comes at opposite end of the current fragment current_matches[curr].reset(); // Reset matches for this fragment to mark it as traversed current_matches[curr^1].reset(); curr = next; } // Add new offset for fragment (assuming we added anything) if(result.offsets.back() != result.flat.size()) { result.offsets.append(result.flat.size()); } } return result.freeze(); }