Changeset e2bbd0c in subsurface
 Timestamp:
 Feb 9, 2017, 9:30:49 PM (4 months ago)
 Branches:
 master
 Children:
 0e7d899
 Parents:
 8f97c4a8
 gitauthor:
 Linus Torvalds <torvalds@…> (02/08/17 11:36:08)
 gitcommitter:
 Dirk Hohndel <dirk@…> (02/09/17 21:30:49)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

core/dive.c
r0277d5a re2bbd0c 1979 1979 int sensor; 1980 1980 1981 if (!s>cylinderpressure.mbar)1982 continue;1983 1981 sensor = mapping[s>sensor]; 1984 1982 if (sensor >= 0) … … 2011 2009 } 2012 2010 2011 static int same_gasmix(struct gasmix *a, struct gasmix *b) 2012 { 2013 if (gasmix_is_air(a) && gasmix_is_air(b)) 2014 return 1; 2015 return a>o2.permille == b>o2.permille && a>he.permille == b>he.permille; 2016 } 2017 2018 /* 2019 * Can we find an exact match for a cylinder in another dive? 2020 * Take the "already matched" map into account, so that we 2021 * don't match multiple similar cylinders to one target. 2022 */ 2023 static int match_cylinder(cylinder_t *cyl, struct dive *dive, unsigned int available) 2024 { 2025 int i; 2026 2027 for (i = 0; i < MAX_CYLINDERS; i++) { 2028 cylinder_t *target; 2029 2030 if (!(available & (1u << i))) 2031 continue; 2032 target = dive>cylinder + i; 2033 if (!same_gasmix(&cyl>gasmix, &target>gasmix)) 2034 continue; 2035 2036 /* FIXME! Should we check sizes too? */ 2037 return i; 2038 } 2039 return 1; 2040 } 2041 2042 /* 2043 * Note: we only allocate from the end, not in holes in the middle. 2044 * So we don't look for empty bits, we look for "no more bits set". 2045 * We could use some "find last bit set" math function, but let's 2046 * not be fancy. 2047 */ 2048 static int find_unused_cylinder(unsigned int used_map) 2049 { 2050 int i; 2051 2052 for (i = 0; i < MAX_CYLINDERS; i++) { 2053 if (!used_map) 2054 return i; 2055 used_map >>= 1; 2056 } 2057 return 1; 2058 } 2059 2013 2060 /* 2014 2061 * Merging cylinder information is nontrivial, because the two dive computers … … 2021 2068 static void merge_cylinders(struct dive *res, struct dive *a, struct dive *b) 2022 2069 { 2023 int i, renumber = 0;2070 int i, last, renumber = 0; 2024 2071 int mapping[MAX_CYLINDERS]; 2025 unsigned int used = 0; 2026 2027 /* Copy the cylinder info raw from 'a' */ 2072 unsigned int used_in_a = 0, used_in_b = 0, matched = 0; 2073 2074 /* Calculate usage map of cylinders */ 2075 for (i = 0; i < MAX_CYLINDERS; i++) { 2076 if (!cylinder_none(a>cylinder+i)  is_cylinder_used(a, i)) 2077 used_in_a = 1u << i; 2078 if (!cylinder_none(b>cylinder+i)  is_cylinder_used(b, i)) 2079 used_in_b = 1u << i; 2080 } 2081 2082 /* For each cylinder in 'b', try to match up things */ 2083 for (i = 0; i < MAX_CYLINDERS; i++) { 2084 int j; 2085 2086 mapping[i] = 1; 2087 if (!(used_in_b & (1u << i))) 2088 continue; 2089 2090 j = match_cylinder(b>cylinder+i, a, used_in_a & ~matched); 2091 if (j < 0) 2092 continue; 2093 2094 /* 2095 * If we had a successful match, we: 2096 * 2097 *  save that in the mapping table 2098 * 2099 *  mark it as matched so that another cylinder in 'b' 2100 * will no longer match 2101 * 2102 *  mark 'b' as needing renumbering if the index changed 2103 */ 2104 mapping[i] = j; 2105 matched = 1u << j; 2106 if (j != i) 2107 renumber = 1; 2108 } 2109 2110 /* 2111 * Consider all the cylinders we matched as used, whether they 2112 * originally were or not (either in 'a' or 'b'). 2113 */ 2114 used_in_a = matched; 2115 2116 /* Now copy all the cylinder info raw from 'a' (whether used/matched or not) */ 2028 2117 memcpy(res>cylinder, a>cylinder, sizeof(res>cylinder)); 2029 2118 memset(a>cylinder, 0, sizeof(a>cylinder)); 2030 2119 2031 if (strcmp(b>dc.model, "planned dive")) { 2032 // We merge two actual dive 2033 for (i = 0; i < MAX_CYLINDERS; i++) { 2034 int j; 2035 cylinder_t *cyl = b>cylinder + i; 2036 2037 j = find_cylinder_match(cyl, res>cylinder, used); 2038 mapping[i] = j; 2039 if (j < 0) 2040 continue; 2041 used = 1 << j; 2042 merge_cylinder_info(cyl, res>cylinder + j); 2043 2044 /* If that renumbered the cylinders, fix it up! */ 2045 if (i != j) 2046 renumber = 1; 2047 } 2048 if (renumber) 2049 cylinder_renumber(b, mapping); 2050 } else { 2051 int j=0; 2052 for (i = 0; i < MAX_CYLINDERS && j < MAX_CYLINDERS; i++) { 2053 if (is_cylinder_used(res, i)) 2054 continue; 2055 2056 while (!is_cylinder_used(b, j) && j < MAX_CYLINDERS  1) { 2057 mapping[j] = 0; 2058 ++j; 2059 } 2060 memcpy(&res>cylinder[i], &b>cylinder[j], sizeof (b>cylinder[j])); 2061 mapping[j] = i; 2062 ++j; 2063 } 2064 bool warn = false; 2065 while (j < MAX_CYLINDERS) { 2066 if (is_cylinder_used(b, j)) 2067 warn = true; 2068 mapping[j++] = 0; 2069 } 2070 if (warn) { 2071 report_error("Could not merge all cylinders as number exceeds %d", MAX_CYLINDERS); 2072 } 2120 /* 2121 * Go back to 'b' and remap any remaining cylinders that didn't 2122 * match completely. 2123 */ 2124 for (i = 0; i < MAX_CYLINDERS; i++) { 2125 int j; 2126 2127 /* Already remapped, or not interesting? */ 2128 if (mapping[i] >= 0) 2129 continue; 2130 if (!(used_in_b & (1u << i))) 2131 continue; 2132 2133 j = find_unused_cylinder(used_in_a); 2134 if (j < 0) 2135 continue; 2136 2137 res>cylinder[j] = b>cylinder[i]; 2138 memset(b>cylinder+i, 0, sizeof(cylinder_t)); 2139 mapping[i] = j; 2140 used_in_a = 1u << j; 2141 if (i != j) 2142 renumber = 1; 2143 } 2144 2145 if (renumber) 2073 2146 cylinder_renumber(b, mapping); 2074 }2075 2147 } 2076 2148
Note: See TracChangeset
for help on using the changeset viewer.