mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	core: move cylinder related functions to struct dive
Seems natural in a C++ code base. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
		
							parent
							
								
									3aab33ba4c
								
							
						
					
					
						commit
						1b593dc56c
					
				
					 29 changed files with 250 additions and 259 deletions
				
			
		|  | @ -198,7 +198,7 @@ void export_TeX(const char *filename, bool selected_only, bool plain, ExportCall | |||
| 		put_format(&buf, "\n%% Gas use information:\n"); | ||||
| 		int qty_cyl = 0; | ||||
| 		for (auto [i, cyl]: enumerated_range(dive->cylinders)) { | ||||
| 			if (is_cylinder_used(dive.get(), i) || (prefs.include_unused_tanks && !cyl.type.description.empty())){ | ||||
| 			if (dive->is_cylinder_used(i) || (prefs.include_unused_tanks && !cyl.type.description.empty())){ | ||||
| 				put_format(&buf, "\\def\\%scyl%cdescription{%s}\n", ssrf, 'a' + i, cyl.type.description.c_str()); | ||||
| 				put_format(&buf, "\\def\\%scyl%cgasname{%s}\n", ssrf, 'a' + i, gasname(cyl.gasmix)); | ||||
| 				put_format(&buf, "\\def\\%scyl%cmixO2{%.1f\\%%}\n", ssrf, 'a' + i, get_o2(cyl.gasmix)/10.0); | ||||
|  |  | |||
|  | @ -1146,7 +1146,7 @@ EditCylinderBase::EditCylinderBase(int index, bool currentDiveOnly, bool nonProt | |||
| 		dives.clear(); | ||||
| 		return; | ||||
| 	} | ||||
| 	const cylinder_t &orig = *get_cylinder(current, index); | ||||
| 	const cylinder_t &orig = *current->get_cylinder(index); | ||||
| 
 | ||||
| 	std::vector<dive *> divesNew; | ||||
| 	divesNew.reserve(dives.size()); | ||||
|  | @ -1156,7 +1156,7 @@ EditCylinderBase::EditCylinderBase(int index, bool currentDiveOnly, bool nonProt | |||
| 	for (dive *d: dives) { | ||||
| 		if (index >= static_cast<int>(d->cylinders.size())) | ||||
| 			continue; | ||||
| 		if (nonProtectedOnly && is_cylinder_prot(d, index)) | ||||
| 		if (nonProtectedOnly && d->is_cylinder_prot(index)) | ||||
| 			continue; | ||||
| 		// We checked that the cylinder exists above.
 | ||||
| 		const cylinder_t &cylinder = d->cylinders[index]; | ||||
|  | @ -1272,7 +1272,7 @@ void EditCylinder::redo() | |||
| 	for (size_t i = 0; i < dives.size(); ++i) { | ||||
| 		const std::string &name = cyl[i].type.description; | ||||
| 		set_tank_info_data(tank_info_table, name, cyl[i].type.size, cyl[i].type.workingpressure); | ||||
| 		std::swap(*get_cylinder(dives[i], indexes[i]), cyl[i]); | ||||
| 		std::swap(*dives[i]->get_cylinder(indexes[i]), cyl[i]); | ||||
| 		divelog.dives.update_cylinder_related_info(*dives[i]); | ||||
| 		emit diveListNotifier.cylinderEdited(dives[i], indexes[i]); | ||||
| 		invalidate_dive_cache(dives[i]); // Ensure that dive is written in git_save()
 | ||||
|  |  | |||
|  | @ -372,7 +372,7 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct | |||
| 	 */ | ||||
| 	read_bytes(2); | ||||
| 	if (tmp_2bytes != 0x7FFF && dt_dive->cylinders.size() > 0) | ||||
| 		get_cylinder(dt_dive, 0)->gas_used.mliter = lrint(get_cylinder(dt_dive, 0)->type.size.mliter * (tmp_2bytes / 100.0)); | ||||
| 		dt_dive->get_cylinder(0)->gas_used.mliter = lrint(dt_dive->get_cylinder(0)->type.size.mliter * (tmp_2bytes / 100.0)); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Dive Type 1 -  Bit table. Subsurface don't have this record, but | ||||
|  | @ -544,10 +544,10 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct | |||
| 			goto bail; | ||||
| 		} | ||||
| 		if (is_nitrox && dt_dive->cylinders.size() > 0) | ||||
| 			get_cylinder(dt_dive, 0)->gasmix.o2.permille = | ||||
| 			dt_dive->get_cylinder(0)->gasmix.o2.permille = | ||||
| 					lrint(membuf[23] & 0x0F ? 20.0 + 2 * (membuf[23] & 0x0F) : 21.0) * 10; | ||||
| 		if (is_O2 && dt_dive->cylinders.size() > 0) | ||||
| 			get_cylinder(dt_dive, 0)->gasmix.o2.permille = membuf[23] * 10; | ||||
| 			dt_dive->get_cylinder(0)->gasmix.o2.permille = membuf[23] * 10; | ||||
| 		free(compl_buffer); | ||||
| 	} | ||||
| 	JUMP(membuf, profile_length); | ||||
|  | @ -560,8 +560,8 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct | |||
| 	else | ||||
| 		dt_dive->dcs[0].deviceid = 0xffffffff; | ||||
| 	if (!is_SCR && dt_dive->cylinders.size() > 0) { | ||||
| 		get_cylinder(dt_dive, 0)->end.mbar = get_cylinder(dt_dive, 0)->start.mbar - | ||||
| 			((get_cylinder(dt_dive, 0)->gas_used.mliter / get_cylinder(dt_dive, 0)->type.size.mliter) * 1000); | ||||
| 		dt_dive->get_cylinder(0)->end.mbar = dt_dive->get_cylinder(0)->start.mbar - | ||||
| 			((dt_dive->get_cylinder(0)->gas_used.mliter / dt_dive->get_cylinder(0)->type.size.mliter) * 1000); | ||||
| 	} | ||||
| 	return (char *)membuf; | ||||
| bail: | ||||
|  | @ -638,8 +638,8 @@ static void wlog_compl_parser(std::string &wl_mem, struct dive *dt_dive, int dco | |||
| 	 */ | ||||
| 	tmp = (int) two_bytes_to_int(runner[pos_tank_init + 1], runner[pos_tank_init]); | ||||
| 	if (tmp != 0x7fff) { | ||||
| 		get_cylinder(dt_dive, 0)->start.mbar = tmp * 10; | ||||
| 		get_cylinder(dt_dive, 0)->end.mbar =  get_cylinder(dt_dive, 0)->start.mbar - lrint(get_cylinder(dt_dive, 0)->gas_used.mliter / get_cylinder(dt_dive, 0)->type.size.mliter) * 1000; | ||||
| 		dt_dive->get_cylinder(0)->start.mbar = tmp * 10; | ||||
| 		dt_dive->get_cylinder(0)->end.mbar =  dt_dive->get_cylinder(0)->start.mbar - lrint(dt_dive->get_cylinder(0)->gas_used.mliter / dt_dive->get_cylinder(0)->type.size.mliter) * 1000; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
|  |  | |||
							
								
								
									
										177
									
								
								core/dive.cpp
									
										
									
									
									
								
							
							
						
						
									
										177
									
								
								core/dive.cpp
									
										
									
									
									
								
							|  | @ -14,6 +14,7 @@ | |||
| #include "divelist.h" | ||||
| #include "divelog.h" | ||||
| #include "divesite.h" | ||||
| #include "equipment.h" | ||||
| #include "errorhelper.h" | ||||
| #include "event.h" | ||||
| #include "extradata.h" | ||||
|  | @ -51,6 +52,19 @@ dive::dive(dive &&) = default; | |||
| dive &dive::operator=(const dive &) = default; | ||||
| dive::~dive() = default; | ||||
| 
 | ||||
| /* get_cylinder_idx_by_use(): Find the index of the first cylinder with a particular CCR use type.
 | ||||
|  * The index returned corresponds to that of the first cylinder with a cylinder_use that | ||||
|  * equals the appropriate enum value [oxygen, diluent, bailout] given by cylinder_use_type. | ||||
|  * A negative number returned indicates that a match could not be found. | ||||
|  * Call parameters: dive = the dive being processed | ||||
|  *                  cylinder_use_type = an enum, one of {oxygen, diluent, bailout} */ | ||||
| static int get_cylinder_idx_by_use(const struct dive &dive, enum cylinderuse cylinder_use_type) | ||||
| { | ||||
| 	auto it = std::find_if(dive.cylinders.begin(), dive.cylinders.end(), [cylinder_use_type] | ||||
| 			       (auto &cyl) { return cyl.cylinder_use == cylinder_use_type; }); | ||||
| 	return it != dive.cylinders.end() ? it - dive.cylinders.begin() : -1; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * The legacy format for sample pressures has a single pressure | ||||
|  * for each sample that can have any sensor, plus a possible | ||||
|  | @ -66,7 +80,7 @@ int legacy_format_o2pressures(const struct dive *dive, const struct divecomputer | |||
| { | ||||
| 	int o2sensor; | ||||
| 
 | ||||
| 	o2sensor = (dc->divemode == CCR) ? get_cylinder_idx_by_use(dive, OXYGEN) : -1; | ||||
| 	o2sensor = (dc->divemode == CCR) ? get_cylinder_idx_by_use(*dive, OXYGEN) : -1; | ||||
| 	for (const auto &s: dc->samples) { | ||||
| 		int seen_pressure = 0, idx; | ||||
| 
 | ||||
|  | @ -92,11 +106,30 @@ int legacy_format_o2pressures(const struct dive *dive, const struct divecomputer | |||
| 	return o2sensor < 0 ? 256 : o2sensor; | ||||
| } | ||||
| 
 | ||||
| /* access to cylinders is controlled by two functions:
 | ||||
|  * - get_cylinder() returns the cylinder of a dive and supposes that | ||||
|  *   the cylinder with the given index exists. If it doesn't, an error | ||||
|  *   message is printed and the "surface air" cylinder returned. | ||||
|  *   (NOTE: this MUST not be written into!). | ||||
|  * - get_or_create_cylinder() creates an empty cylinder if it doesn't exist. | ||||
|  *   Multiple cylinders might be created if the index is bigger than the | ||||
|  *   number of existing cylinders | ||||
|  */ | ||||
| cylinder_t *dive::get_cylinder(int idx) | ||||
| { | ||||
| 	return &cylinders[idx]; | ||||
| } | ||||
| 
 | ||||
| const cylinder_t *dive::get_cylinder(int idx) const | ||||
| { | ||||
| 	return &cylinders[idx]; | ||||
| } | ||||
| 
 | ||||
| /* warning: does not test idx for validity */ | ||||
| struct event create_gas_switch_event(struct dive *dive, struct divecomputer *dc, int seconds, int idx) | ||||
| { | ||||
| 	/* The gas switch event format is insane for historical reasons */ | ||||
| 	struct gasmix mix = get_cylinder(dive, idx)->gasmix; | ||||
| 	struct gasmix mix = dive->get_cylinder(idx)->gasmix; | ||||
| 	int o2 = get_o2(mix); | ||||
| 	int he = get_he(mix); | ||||
| 
 | ||||
|  | @ -124,13 +157,13 @@ void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int second | |||
| 	add_event_to_dc(dc, std::move(ev)); | ||||
| } | ||||
| 
 | ||||
| struct gasmix get_gasmix_from_event(const struct dive *dive, const struct event &ev) | ||||
| struct gasmix dive::get_gasmix_from_event(const struct event &ev) const | ||||
| { | ||||
| 	if (ev.is_gaschange()) { | ||||
| 		int index = ev.gas.index; | ||||
| 		// FIXME: The planner uses one past cylinder-count to signify "surface air". Remove in due course.
 | ||||
| 		if (index >= 0 && static_cast<size_t>(index) < dive->cylinders.size() + 1) | ||||
| 			return get_cylinder(dive, index)->gasmix; | ||||
| 		if (index >= 0 && static_cast<size_t>(index) < cylinders.size() + 1) | ||||
| 			return get_cylinder(index)->gasmix; | ||||
| 		return ev.gas.mix; | ||||
| 	} | ||||
| 	return gasmix_air; | ||||
|  | @ -240,7 +273,7 @@ void copy_used_cylinders(const struct dive *s, struct dive *d, bool used_only) | |||
| 
 | ||||
| 	d->cylinders.clear(); | ||||
| 	for (auto [i, cyl]: enumerated_range(s->cylinders)) { | ||||
| 		if (!used_only || is_cylinder_used(s, i) || get_cylinder(s, i)->cylinder_use == NOT_USED) | ||||
| 		if (!used_only || s->is_cylinder_used(i) || s->get_cylinder(i)->cylinder_use == NOT_USED) | ||||
| 			d->cylinders.push_back(cyl); | ||||
| 	} | ||||
| } | ||||
|  | @ -308,13 +341,39 @@ static int get_cylinder_used(const struct dive *dive, bool used[]) | |||
| 	return num; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * If the event has an explicit cylinder index, | ||||
|  * we return that. If it doesn't, we return the best | ||||
|  * match based on the gasmix. | ||||
|  * | ||||
|  * Some dive computers give cylinder indices, some | ||||
|  * give just the gas mix. | ||||
|  */ | ||||
| int dive::get_cylinder_index(const struct event &ev) const | ||||
| { | ||||
| 	if (ev.gas.index >= 0) | ||||
| 		return ev.gas.index; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * This should no longer happen! | ||||
| 	 * | ||||
| 	 * We now match up gas change events with their cylinders at dive | ||||
| 	 * event fixup time. | ||||
| 	 */ | ||||
| 	report_info("Still looking up cylinder based on gas mix in get_cylinder_index()!"); | ||||
| 
 | ||||
| 	gasmix mix = get_gasmix_from_event(ev); | ||||
| 	int best = find_best_gasmix_match(mix, cylinders); | ||||
| 	return best < 0 ? 0 : best; | ||||
| } | ||||
| 
 | ||||
| /* Are there any used cylinders which we do not know usage about? */ | ||||
| static bool has_unknown_used_cylinders(const struct dive *dive, const struct divecomputer *dc, | ||||
| static bool has_unknown_used_cylinders(const struct dive &dive, const struct divecomputer *dc, | ||||
| 				       const bool used_cylinders[], int num) | ||||
| { | ||||
| 	int idx; | ||||
| 	auto used_and_unknown = std::make_unique<bool[]>(dive->cylinders.size()); | ||||
| 	std::copy(used_cylinders, used_cylinders + dive->cylinders.size(), used_and_unknown.get()); | ||||
| 	auto used_and_unknown = std::make_unique<bool[]>(dive.cylinders.size()); | ||||
| 	std::copy(used_cylinders, used_cylinders + dive.cylinders.size(), used_and_unknown.get()); | ||||
| 
 | ||||
| 	/* We know about using the O2 cylinder in a CCR dive */ | ||||
| 	if (dc->divemode == CCR) { | ||||
|  | @ -326,7 +385,7 @@ static bool has_unknown_used_cylinders(const struct dive *dive, const struct div | |||
| 	} | ||||
| 
 | ||||
| 	/* We know about the explicit first cylinder (or first) */ | ||||
| 	idx = explicit_first_cylinder(dive, dc); | ||||
| 	idx = dive.explicit_first_cylinder(dc); | ||||
| 	if (idx >= 0 && used_and_unknown[idx]) { | ||||
| 		used_and_unknown[idx] = false; | ||||
| 		num--; | ||||
|  | @ -336,7 +395,7 @@ static bool has_unknown_used_cylinders(const struct dive *dive, const struct div | |||
| 	event_loop loop("gaschange"); | ||||
| 	const struct event *ev; | ||||
| 	while ((ev = loop.next(*dc)) != nullptr && num > 0) { | ||||
| 		idx = get_cylinder_index(dive, *ev); | ||||
| 		idx = dive.get_cylinder_index(*ev); | ||||
| 		if (idx >= 0 && used_and_unknown[idx]) { | ||||
| 			used_and_unknown[idx] = false; | ||||
| 			num--; | ||||
|  | @ -368,7 +427,7 @@ void per_cylinder_mean_depth(const struct dive *dive, struct divecomputer *dc, i | |||
| 	 */ | ||||
| 	auto used_cylinders = std::make_unique<bool[]>(dive->cylinders.size()); | ||||
| 	num_used_cylinders = get_cylinder_used(dive, used_cylinders.get()); | ||||
| 	if (has_unknown_used_cylinders(dive, dc, used_cylinders.get(), num_used_cylinders)) { | ||||
| 	if (has_unknown_used_cylinders(*dive, dc, used_cylinders.get(), num_used_cylinders)) { | ||||
| 		/*
 | ||||
| 		 * If we had more than one used cylinder, but | ||||
| 		 * do not know usage of them, we simply cannot | ||||
|  | @ -401,7 +460,7 @@ void per_cylinder_mean_depth(const struct dive *dive, struct divecomputer *dc, i | |||
| 
 | ||||
| 		/* Make sure to move the event past 'lasttime' */ | ||||
| 		while (ev && lasttime >= ev->time.seconds) { | ||||
| 			idx = get_cylinder_index(dive, *ev); | ||||
| 			idx = dive->get_cylinder_index(*ev); | ||||
| 			ev = loop.next(*dc); | ||||
| 		} | ||||
| 
 | ||||
|  | @ -454,19 +513,19 @@ static int same_rounded_pressure(pressure_t a, pressure_t b) | |||
|  * first cylinder - in which case cylinder 0 is indeed the first cylinder. | ||||
|  * We likewise return 0 if the event concerns a cylinder that doesn't exist. | ||||
|  * If the dive has no cylinders, -1 is returned. */ | ||||
| int explicit_first_cylinder(const struct dive *dive, const struct divecomputer *dc) | ||||
| int dive::explicit_first_cylinder(const struct divecomputer *dc) const | ||||
| { | ||||
| 	int res = 0; | ||||
| 	if (dive->cylinders.empty()) | ||||
| 	if (cylinders.empty()) | ||||
| 		return -1; | ||||
| 	if (dc) { | ||||
| 		const struct event *ev = get_first_event(*dc, "gaschange"); | ||||
| 		if (ev && ((!dc->samples.empty() && ev->time.seconds == dc->samples[0].time.seconds) || ev->time.seconds <= 1)) | ||||
| 			res = get_cylinder_index(dive, *ev); | ||||
| 			res = get_cylinder_index(*ev); | ||||
| 		else if (dc->divemode == CCR) | ||||
| 			res = std::max(get_cylinder_idx_by_use(dive, DILUENT), res); | ||||
| 			res = std::max(get_cylinder_idx_by_use(*this, DILUENT), res); | ||||
| 	} | ||||
| 	return static_cast<size_t>(res) < dive->cylinders.size() ? res : 0; | ||||
| 	return static_cast<size_t>(res) < cylinders.size() ? res : 0; | ||||
| } | ||||
| 
 | ||||
| static double calculate_depth_to_mbarf(int depth, pressure_t surface_pressure, int salinity); | ||||
|  | @ -492,13 +551,13 @@ void update_setpoint_events(const struct dive *dive, struct divecomputer *dc) | |||
| 		// pO2 values we would have computed anyway.
 | ||||
| 		event_loop loop("gaschange"); | ||||
| 		const struct event *ev = loop.next(*dc); | ||||
| 		struct gasmix gasmix = get_gasmix_from_event(dive, *ev); | ||||
| 		struct gasmix gasmix = dive->get_gasmix_from_event(*ev); | ||||
| 		const struct event *next = loop.next(*dc); | ||||
| 
 | ||||
| 		for (auto &sample: dc->samples) { | ||||
| 			if (next && sample.time.seconds >= next->time.seconds) { | ||||
| 				ev = next; | ||||
| 				gasmix = get_gasmix_from_event(dive, *ev); | ||||
| 				gasmix = dive->get_gasmix_from_event(*ev); | ||||
| 				next = loop.next(*dc); | ||||
| 			} | ||||
| 			gas_pressures pressures = fill_pressures(lrint(calculate_depth_to_mbarf(sample.depth.mm, dc->surface_pressure, 0)), gasmix ,0, dc->divemode); | ||||
|  | @ -1367,19 +1426,6 @@ pick_b: | |||
| 		add_initial_gaschange(d, res, offset, cylinders_map2[0]); | ||||
| } | ||||
| 
 | ||||
| /* get_cylinder_idx_by_use(): Find the index of the first cylinder with a particular CCR use type.
 | ||||
|  * The index returned corresponds to that of the first cylinder with a cylinder_use that | ||||
|  * equals the appropriate enum value [oxygen, diluent, bailout] given by cylinder_use_type. | ||||
|  * A negative number returned indicates that a match could not be found. | ||||
|  * Call parameters: dive = the dive being processed | ||||
|  *                  cylinder_use_type = an enum, one of {oxygen, diluent, bailout} */ | ||||
| int get_cylinder_idx_by_use(const struct dive *dive, enum cylinderuse cylinder_use_type) | ||||
| { | ||||
| 	auto it = std::find_if(dive->cylinders.begin(), dive->cylinders.end(), [cylinder_use_type] | ||||
| 			       (auto &cyl) { return cyl.cylinder_use == cylinder_use_type; }); | ||||
| 	return it != dive->cylinders.end() ? it - dive->cylinders.begin() : -1; | ||||
| } | ||||
| 
 | ||||
| /* Force an initial gaschange event to the (old) gas #0 */ | ||||
| static void add_initial_gaschange(struct dive &dive, struct divecomputer &dc, int offset, int idx) | ||||
| { | ||||
|  | @ -1472,7 +1518,7 @@ int same_gasmix_cylinder(const cylinder_t &cyl, int cylid, const struct dive *di | |||
| 		if (i == cylid) | ||||
| 			continue; | ||||
| 		struct gasmix gas2 = cyl.gasmix; | ||||
| 		if (gasmix_distance(mygas, gas2) == 0 && (is_cylinder_used(dive, i) || check_unused)) | ||||
| 		if (gasmix_distance(mygas, gas2) == 0 && (dive->is_cylinder_used(i) || check_unused)) | ||||
| 			return i; | ||||
| 	} | ||||
| 	return -1; | ||||
|  | @ -1598,7 +1644,7 @@ static bool cylinder_in_use(const struct dive *dive, int idx) | |||
| 		return false; | ||||
| 
 | ||||
| 	/* This tests for gaschange events or pressure changes */ | ||||
| 	if (is_cylinder_used(dive, idx) || prefs.include_unused_tanks) | ||||
| 	if (dive->is_cylinder_used(idx) || prefs.include_unused_tanks) | ||||
| 		return true; | ||||
| 
 | ||||
| 	/* This tests for typenames or gas contents */ | ||||
|  | @ -1660,7 +1706,7 @@ static void merge_cylinders(struct dive &res, const struct dive &a, const struct | |||
| 		if (!used_in_b[i]) | ||||
| 			continue; | ||||
| 
 | ||||
| 		j = match_cylinder(get_cylinder(&b, i), res, try_to_match.get()); | ||||
| 		j = match_cylinder(b.get_cylinder(i), res, try_to_match.get()); | ||||
| 
 | ||||
| 		/* No match? Add it to the result */ | ||||
| 		if (j < 0) { | ||||
|  | @ -1672,7 +1718,7 @@ static void merge_cylinders(struct dive &res, const struct dive &a, const struct | |||
| 
 | ||||
| 		/* Otherwise, merge the result to the one we found */ | ||||
| 		mapping_b[i] = j; | ||||
| 		merge_one_cylinder(get_cylinder(&res, j), get_cylinder(&b, i)); | ||||
| 		merge_one_cylinder(res.get_cylinder(j), b.get_cylinder(i)); | ||||
| 
 | ||||
| 		/* Don't match the same target more than once */ | ||||
| 		try_to_match[j] = false; | ||||
|  | @ -2589,8 +2635,8 @@ gasmix_loop::gasmix_loop(const struct dive &d, const struct divecomputer &dc) : | |||
| 		return; | ||||
| 
 | ||||
| 	/* on first invocation, get initial gas mix and first event (if any) */ | ||||
| 	int cyl = explicit_first_cylinder(&dive, &dc); | ||||
| 	last = get_cylinder(&dive, cyl)->gasmix; | ||||
| 	int cyl = dive.explicit_first_cylinder(&dc); | ||||
| 	last = dive.get_cylinder(cyl)->gasmix; | ||||
| 	ev = loop.next(dc); | ||||
| } | ||||
| 
 | ||||
|  | @ -2601,7 +2647,7 @@ gasmix gasmix_loop::next(int time) | |||
| 		return last; | ||||
| 
 | ||||
| 	while (ev && ev->time.seconds <= time) { | ||||
| 		last = get_gasmix_from_event(&dive, *ev); | ||||
| 		last = dive.get_gasmix_from_event(*ev); | ||||
| 		ev = loop.next(dc); | ||||
| 	} | ||||
| 	return last; | ||||
|  | @ -2609,9 +2655,9 @@ gasmix gasmix_loop::next(int time) | |||
| 
 | ||||
| /* get the gas at a certain time during the dive */ | ||||
| /* If there is a gasswitch at that time, it returns the new gasmix */ | ||||
| struct gasmix get_gasmix_at_time(const struct dive &d, const struct divecomputer &dc, duration_t time) | ||||
| struct gasmix dive::get_gasmix_at_time(const struct divecomputer &dc, duration_t time) const | ||||
| { | ||||
| 	return gasmix_loop(d, dc).next(time.seconds); | ||||
| 	return gasmix_loop(*this, dc).next(time.seconds); | ||||
| } | ||||
| 
 | ||||
| /* Does that cylinder have any pressure readings? */ | ||||
|  | @ -2682,7 +2728,7 @@ dive::get_maximal_gas_result dive::get_maximal_gas() const | |||
| 		int o2 = get_o2(cyl.gasmix); | ||||
| 		int he = get_he(cyl.gasmix); | ||||
| 
 | ||||
| 		if (!is_cylinder_used(this, i)) | ||||
| 		if (!is_cylinder_used(i)) | ||||
| 			continue; | ||||
| 		if (cyl.cylinder_use == OXYGEN) | ||||
| 			continue; | ||||
|  | @ -2703,3 +2749,48 @@ dive::get_maximal_gas_result dive::get_maximal_gas() const | |||
| 		maxo2 = mino2 = 0; | ||||
| 	return { mino2, maxhe, maxo2 }; | ||||
| } | ||||
| 
 | ||||
| bool dive::has_gaschange_event(const struct divecomputer *dc, int idx) const | ||||
| { | ||||
| 	bool first_gas_explicit = false; | ||||
| 	event_loop loop("gaschange"); | ||||
| 	while (auto event = loop.next(*dc)) { | ||||
| 		if (!dc->samples.empty() && (event->time.seconds == 0 || | ||||
| 				   (dc->samples[0].time.seconds == event->time.seconds))) | ||||
| 			first_gas_explicit = true; | ||||
| 		if (get_cylinder_index(*event) == idx) | ||||
| 			return true; | ||||
| 	} | ||||
| 	return !first_gas_explicit && idx == 0; | ||||
| } | ||||
| 
 | ||||
| bool dive::is_cylinder_used(int idx) const | ||||
| { | ||||
| 	if (idx < 0 || static_cast<size_t>(idx) >= cylinders.size()) | ||||
| 		return false; | ||||
| 
 | ||||
| 	const cylinder_t &cyl = cylinders[idx]; | ||||
| 	if ((cyl.start.mbar - cyl.end.mbar) > SOME_GAS) | ||||
| 		return true; | ||||
| 
 | ||||
| 	if ((cyl.sample_start.mbar - cyl.sample_end.mbar) > SOME_GAS) | ||||
| 		return true; | ||||
| 
 | ||||
| 	for (auto &dc: dcs) { | ||||
| 		if (has_gaschange_event(&dc, idx)) | ||||
| 			return true; | ||||
| 		else if (dc.divemode == CCR && idx == get_cylinder_idx_by_use(*this, OXYGEN)) | ||||
| 			return true; | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| bool dive::is_cylinder_prot(int idx) const | ||||
| { | ||||
| 	if (idx < 0 || static_cast<size_t>(idx) >= cylinders.size()) | ||||
| 		return false; | ||||
| 
 | ||||
| 	return std::any_of(dcs.begin(), dcs.end(), | ||||
| 			   [this, idx](auto &dc) | ||||
| 			   { return has_gaschange_event(&dc, idx); }); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										20
									
								
								core/dive.h
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								core/dive.h
									
										
									
									
									
								
							|  | @ -91,6 +91,15 @@ struct dive { | |||
| 	bool is_planned() const; | ||||
| 	bool is_logged() const; | ||||
| 	bool likely_same(const struct dive &b) const; | ||||
| 	bool is_cylinder_used(int idx) const; | ||||
| 	bool is_cylinder_prot(int idx) const; | ||||
| 	int explicit_first_cylinder(const struct divecomputer *dc) const; | ||||
| 	int get_cylinder_index(const struct event &ev) const; | ||||
| 	bool has_gaschange_event(const struct divecomputer *dc, int idx) const; | ||||
| 	struct gasmix get_gasmix_from_event(const struct event &ev) const; | ||||
| 	struct gasmix get_gasmix_at_time(const struct divecomputer &dc, duration_t time) const; | ||||
| 	cylinder_t *get_cylinder(int idx); | ||||
| 	const cylinder_t *get_cylinder(int idx) const; | ||||
| 
 | ||||
| 	int depth_to_mbar(int depth) const; | ||||
| 	double depth_to_mbarf(int depth) const; | ||||
|  | @ -115,7 +124,6 @@ struct dive_or_trip { | |||
| extern void invalidate_dive_cache(struct dive *dive); | ||||
| extern bool dive_cache_is_valid(const struct dive *dive); | ||||
| 
 | ||||
| extern int get_cylinder_idx_by_use(const struct dive *dive, enum cylinderuse cylinder_use_type); | ||||
| extern void cylinder_renumber(struct dive &dive, int mapping[]); | ||||
| extern int same_gasmix_cylinder(const cylinder_t &cyl, int cylid, const struct dive *dive, bool check_unused); | ||||
| 
 | ||||
|  | @ -139,9 +147,6 @@ struct dive_components { | |||
| 	unsigned int when : 1; | ||||
| }; | ||||
| 
 | ||||
| extern bool has_gaschange_event(const struct dive *dive, const struct divecomputer *dc, int idx); | ||||
| extern int explicit_first_cylinder(const struct dive *dive, const struct divecomputer *dc); | ||||
| 
 | ||||
| extern fraction_t best_o2(depth_t depth, const struct dive *dive, bool in_planner); | ||||
| extern fraction_t best_he(depth_t depth, const struct dive *dive, bool o2narcotic, fraction_t fo2); | ||||
| 
 | ||||
|  | @ -193,13 +198,9 @@ extern int dive_getUniqID(); | |||
| 
 | ||||
| extern void copy_events_until(const struct dive *sd, struct dive *dd, int dcNr, int time); | ||||
| extern void copy_used_cylinders(const struct dive *s, struct dive *d, bool used_only); | ||||
| extern bool is_cylinder_used(const struct dive *dive, int idx); | ||||
| extern bool is_cylinder_prot(const struct dive *dive, int idx); | ||||
| extern void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int time, int idx); | ||||
| extern struct event create_gas_switch_event(struct dive *dive, struct divecomputer *dc, int seconds, int idx); | ||||
| extern void per_cylinder_mean_depth(const struct dive *dive, struct divecomputer *dc, int *mean, int *duration); | ||||
| extern int get_cylinder_index(const struct dive *dive, const struct event &ev); | ||||
| extern struct gasmix get_gasmix_from_event(const struct dive *, const struct event &ev); | ||||
| extern bool cylinder_with_sensor_sample(const struct dive *dive, int cylinder_id); | ||||
| 
 | ||||
| /* UI related protopypes */ | ||||
|  | @ -208,9 +209,6 @@ extern void invalidate_dive_cache(struct dive *dc); | |||
| 
 | ||||
| extern int total_weight(const struct dive *); | ||||
| 
 | ||||
| /* Get gasmix at a given time */ | ||||
| extern struct gasmix get_gasmix_at_time(const struct dive &dive, const struct divecomputer &dc, duration_t time); | ||||
| 
 | ||||
| extern void update_setpoint_events(const struct dive *dive, struct divecomputer *dc); | ||||
| 
 | ||||
| /* Make pointers to dive and dive_trip "Qt metatypes" so that they can be passed through
 | ||||
|  |  | |||
|  | @ -117,7 +117,7 @@ int total_weight(const struct dive *dive) | |||
| 
 | ||||
| static int active_o2(const struct dive &dive, const struct divecomputer *dc, duration_t time) | ||||
| { | ||||
| 	struct gasmix gas = get_gasmix_at_time(dive, *dc, time); | ||||
| 	struct gasmix gas = dive.get_gasmix_at_time(*dc, time); | ||||
| 	return get_o2(gas); | ||||
| } | ||||
| 
 | ||||
|  | @ -137,8 +137,8 @@ static int get_sample_o2(const struct dive &dive, const struct divecomputer *dc, | |||
| 		double amb_presure = dive.depth_to_bar(sample.depth.mm); | ||||
| 		double pamb_pressure = dive.depth_to_bar(psample.depth.mm ); | ||||
| 		if (dc->divemode == PSCR) { | ||||
| 			po2i = pscr_o2(pamb_pressure, get_gasmix_at_time(dive, *dc, psample.time)); | ||||
| 			po2f = pscr_o2(amb_presure, get_gasmix_at_time(dive, *dc, sample.time)); | ||||
| 			po2i = pscr_o2(pamb_pressure, dive.get_gasmix_at_time(*dc, psample.time)); | ||||
| 			po2f = pscr_o2(amb_presure, dive.get_gasmix_at_time(*dc, sample.time)); | ||||
| 		} else { | ||||
| 			int o2 = active_o2(dive, dc, psample.time);	// 	... calculate po2 from depth and FiO2.
 | ||||
| 			po2i = lrint(o2 * pamb_pressure);	// (initial) po2 at start of segment
 | ||||
|  | @ -182,8 +182,8 @@ static int calculate_otu(const struct dive &dive) | |||
| 				double amb_presure = dive.depth_to_bar(sample.depth.mm); | ||||
| 				double pamb_pressure = dive.depth_to_bar(psample.depth.mm); | ||||
| 				if (dc->divemode == PSCR) { | ||||
| 					po2i = pscr_o2(pamb_pressure, get_gasmix_at_time(dive, *dc, psample.time)); | ||||
| 					po2f = pscr_o2(amb_presure, get_gasmix_at_time(dive, *dc, sample.time)); | ||||
| 					po2i = pscr_o2(pamb_pressure, dive.get_gasmix_at_time(*dc, psample.time)); | ||||
| 					po2f = pscr_o2(amb_presure, dive.get_gasmix_at_time(*dc, sample.time)); | ||||
| 				} else { | ||||
| 					int o2 = active_o2(dive, dc, psample.time);	// 	... calculate po2 from depth and FiO2.
 | ||||
| 					po2i = lrint(o2 * pamb_pressure);	// (initial) po2 at start of segment
 | ||||
|  | @ -388,7 +388,7 @@ static double calculate_airuse(const struct dive &dive) | |||
| 			// better not pretend we know the total gas use.
 | ||||
| 			// Eventually, logic should be fixed to compute average depth and total time
 | ||||
| 			// for those segments where cylinders with known pressure drop are breathed from.
 | ||||
| 			if (is_cylinder_used(&dive, i)) | ||||
| 			if (dive.is_cylinder_used(i)) | ||||
| 				return 0.0; | ||||
| 			else | ||||
| 				continue; | ||||
|  |  | |||
|  | @ -369,25 +369,6 @@ cylinder_t *add_empty_cylinder(struct cylinder_table *t) | |||
| 	return &t->back(); | ||||
| } | ||||
| 
 | ||||
| /* access to cylinders is controlled by two functions:
 | ||||
|  * - get_cylinder() returns the cylinder of a dive and supposes that | ||||
|  *   the cylinder with the given index exists. If it doesn't, an error | ||||
|  *   message is printed and the "surface air" cylinder returned. | ||||
|  *   (NOTE: this MUST not be written into!). | ||||
|  * - get_or_create_cylinder() creates an empty cylinder if it doesn't exist. | ||||
|  *   Multiple cylinders might be created if the index is bigger than the | ||||
|  *   number of existing cylinders | ||||
|  */ | ||||
| cylinder_t *get_cylinder(struct dive *d, int idx) | ||||
| { | ||||
| 	return &d->cylinders[idx]; | ||||
| } | ||||
| 
 | ||||
| const cylinder_t *get_cylinder(const struct dive *d, int idx) | ||||
| { | ||||
| 	return &d->cylinders[idx]; | ||||
| } | ||||
| 
 | ||||
| cylinder_t *get_or_create_cylinder(struct dive *d, int idx) | ||||
| { | ||||
| 	if (idx < 0) { | ||||
|  | @ -468,7 +449,7 @@ void add_default_cylinder(struct dive *d) | |||
| 
 | ||||
| static bool show_cylinder(const struct dive *d, int i) | ||||
| { | ||||
| 	if (is_cylinder_used(d, i)) | ||||
| 	if (d->is_cylinder_used(i)) | ||||
| 		return true; | ||||
| 
 | ||||
| 	const cylinder_t &cyl = d->cylinders[i]; | ||||
|  | @ -499,7 +480,7 @@ void dump_cylinders(struct dive *dive, bool verbose) | |||
| { | ||||
| 	printf("Cylinder list:\n"); | ||||
| 	for (int i = 0; i < dive->cylinders; i++) { | ||||
| 		cylinder_t *cyl = get_cylinder(dive, i); | ||||
| 		cylinder_t *cyl = dive->get_cylinder(i); | ||||
| 
 | ||||
| 		printf("%02d: Type     %s, %3.1fl, %3.0fbar\n", i, cyl->type.description.c_str(), cyl->type.size.mliter / 1000.0, cyl->type.workingpressure.mbar / 1000.0); | ||||
| 		printf("    Gasmix   O2 %2.0f%% He %2.0f%%\n", cyl->gasmix.o2.permille / 10.0, cyl->gasmix.he.permille / 10.0); | ||||
|  |  | |||
|  | @ -71,8 +71,6 @@ using weightsystem_table = std::vector<weightsystem_t>; | |||
| extern enum cylinderuse cylinderuse_from_text(const char *text); | ||||
| extern void copy_cylinder_types(const struct dive *s, struct dive *d); | ||||
| extern cylinder_t *add_empty_cylinder(struct cylinder_table *t); | ||||
| extern cylinder_t *get_cylinder(struct dive *d, int idx); | ||||
| extern const cylinder_t *get_cylinder(const struct dive *d, int idx); | ||||
| extern cylinder_t *get_or_create_cylinder(struct dive *d, int idx); | ||||
| extern bool same_weightsystem(weightsystem_t w1, weightsystem_t w2); | ||||
| extern void remove_cylinder(struct dive *dive, int idx); | ||||
|  |  | |||
|  | @ -187,7 +187,7 @@ static void fill_missing_tank_pressures(const struct dive *dive, struct plot_inf | |||
| 	if (track_pr.empty()) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (get_cylinder(dive, cyl)->cylinder_use == OC_GAS) | ||||
| 	if (dive->get_cylinder(cyl)->cylinder_use == OC_GAS) | ||||
| 		strategy = SAC; | ||||
| 	else | ||||
| 		strategy = TIME; | ||||
|  | @ -248,7 +248,7 @@ static void fill_missing_tank_pressures(const struct dive *dive, struct plot_inf | |||
| 			last_segment = it; | ||||
| 		} | ||||
| 
 | ||||
| 		if(get_cylinder(dive, cyl)->cylinder_use == OC_GAS) { | ||||
| 		if(dive->get_cylinder(cyl)->cylinder_use == OC_GAS) { | ||||
| 
 | ||||
| 			/* if this segment has pressure_time, then calculate a new interpolated pressure */ | ||||
| 			if (interpolate.pressure_time) { | ||||
|  | @ -310,7 +310,7 @@ static void debug_print_pressures(struct plot_info &pi) | |||
| void populate_pressure_information(const struct dive *dive, const struct divecomputer *dc, struct plot_info &pi, int sensor) | ||||
| { | ||||
| 	int first, last, cyl; | ||||
| 	const cylinder_t *cylinder = get_cylinder(dive, sensor); | ||||
| 	const cylinder_t *cylinder = dive->get_cylinder(sensor); | ||||
| 	std::vector<pr_track_t> track; | ||||
| 	size_t current = std::string::npos; | ||||
| 	int missing_pr = 0, dense = 1; | ||||
|  | @ -350,7 +350,7 @@ void populate_pressure_information(const struct dive *dive, const struct divecom | |||
| 	 */ | ||||
| 	cyl = sensor; | ||||
| 	event_loop loop_gas("gaschange"); | ||||
| 	const struct event *ev = has_gaschange_event(dive, dc, sensor) ? | ||||
| 	const struct event *ev = dive->has_gaschange_event(dc, sensor) ? | ||||
| 		loop_gas.next(*dc) : nullptr; | ||||
| 	divemode_loop loop_mode(*dc); | ||||
| 
 | ||||
|  | @ -360,7 +360,7 @@ void populate_pressure_information(const struct dive *dive, const struct divecom | |||
| 		int time = entry.sec; | ||||
| 
 | ||||
| 		while (ev && ev->time.seconds <= time) {   // Find 1st gaschange event after 
 | ||||
| 			cyl = get_cylinder_index(dive, *ev); // the current gas change.
 | ||||
| 			cyl = dive->get_cylinder_index(*ev); // the current gas change.
 | ||||
| 			if (cyl < 0) | ||||
| 				cyl = sensor; | ||||
| 			ev = loop_gas.next(*dc); | ||||
|  |  | |||
|  | @ -140,7 +140,7 @@ static int divinglog_profile(void *param, int, char **data, char **) | |||
| 			state->cur_sample->pressure[0].mbar = pressure * 100; | ||||
| 			state->cur_sample->rbt.seconds = rbt; | ||||
| 			if (oldcyl != tank && tank >= 0 && static_cast<size_t>(tank) < state->cur_dive->cylinders.size()) { | ||||
| 				struct gasmix mix = get_cylinder(state->cur_dive.get(), tank)->gasmix; | ||||
| 				struct gasmix mix = state->cur_dive.get()->get_cylinder(tank)->gasmix; | ||||
| 				int o2 = get_o2(mix); | ||||
| 				int he = get_he(mix); | ||||
| 
 | ||||
|  |  | |||
|  | @ -89,7 +89,7 @@ int get_cylinderid_at_time(struct dive *dive, struct divecomputer *dc, duration_ | |||
| 		if (event.time.seconds > time.seconds) | ||||
| 			break; | ||||
| 		if (event.name == "gaschange") | ||||
| 			cylinder_idx = get_cylinder_index(dive, event); | ||||
| 			cylinder_idx = dive->get_cylinder_index(event); | ||||
| 	} | ||||
| 	return cylinder_idx; | ||||
| } | ||||
|  | @ -136,7 +136,7 @@ static int tissue_at_end(struct deco_state *ds, struct dive *dive, const struct | |||
| 						: sample.setpoint; | ||||
| 
 | ||||
| 		duration_t t1 = sample.time; | ||||
| 		struct gasmix gas = get_gasmix_at_time(*dive, *dc, t0); | ||||
| 		struct gasmix gas = dive->get_gasmix_at_time(*dc, t0); | ||||
| 		if (psample) | ||||
| 			lastdepth = psample->depth; | ||||
| 
 | ||||
|  | @ -259,7 +259,7 @@ static void create_dive_from_plan(struct diveplan *diveplan, struct dive *dive, | |||
| 		if (dp->cylinderid != lastcylid) { | ||||
| 			/* need to insert a first sample for the new gas */ | ||||
| 			add_gas_switch_event(dive, dc, lasttime + 1, dp->cylinderid); | ||||
| 			cyl = get_cylinder(dive, dp->cylinderid); // FIXME: This actually may get one past the last cylinder for "surface air".
 | ||||
| 			cyl = dive->get_cylinder(dp->cylinderid); // FIXME: This actually may get one past the last cylinder for "surface air".
 | ||||
| 			if (!cyl) { | ||||
| 				report_error("Invalid cylinder in create_dive_from_plan(): %d", dp->cylinderid); | ||||
| 				continue; | ||||
|  | @ -368,7 +368,7 @@ struct gaschanges { | |||
| 
 | ||||
| static int setpoint_change(struct dive *dive, int cylinderid) | ||||
| { | ||||
| 	cylinder_t *cylinder = get_cylinder(dive, cylinderid); | ||||
| 	cylinder_t *cylinder = dive->get_cylinder(cylinderid); | ||||
| 	if (cylinder->type.description.empty()) | ||||
| 		return 0; | ||||
| 	if (starts_with(cylinder->type.description, "SP ")) { | ||||
|  | @ -422,7 +422,7 @@ static std::vector<gaschanges> analyze_gaslist(struct diveplan *diveplan, struct | |||
| 	for (size_t nr = 0; nr < gaschanges.size(); nr++) { | ||||
| 		int idx = gaschanges[nr].gasidx; | ||||
| 		printf("gaschange nr %d: @ %5.2lfm gasidx %d (%s)\n", nr, gaschanges[nr].depth / 1000.0, | ||||
| 		       idx, gasname(&get_cylinder(&dive, idx)->gasmix)); | ||||
| 		       idx, gasname(&dive.get_cylinder(idx)->gasmix)); | ||||
| 	} | ||||
| #endif | ||||
| 	return gaschanges; | ||||
|  | @ -507,7 +507,7 @@ int ascent_velocity(int depth, int avg_depth, int) | |||
| 
 | ||||
| static void track_ascent_gas(int depth, struct dive *dive, int cylinder_id, int avg_depth, int bottom_time, bool safety_stop, enum divemode_t divemode) | ||||
| { | ||||
| 	cylinder_t *cylinder = get_cylinder(dive, cylinder_id); | ||||
| 	cylinder_t *cylinder = dive->get_cylinder(cylinder_id); | ||||
| 	while (depth > 0) { | ||||
| 		int deltad = ascent_velocity(depth, avg_depth, bottom_time) * base_timestep; | ||||
| 		if (deltad > depth) | ||||
|  | @ -575,7 +575,7 @@ static bool enough_gas(const struct dive *dive, int current_cylinder) | |||
| { | ||||
| 	if (current_cylinder < 0 || static_cast<size_t>(current_cylinder) >= dive->cylinders.size()) | ||||
| 		return false; | ||||
| 	const cylinder_t *cyl = get_cylinder(dive, current_cylinder); | ||||
| 	const cylinder_t *cyl = dive->get_cylinder(current_cylinder); | ||||
| 
 | ||||
| 	if (!cyl->start.mbar) | ||||
| 		return true; | ||||
|  | @ -718,7 +718,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 	// Find the divemode at the end of the dive
 | ||||
| 	divemode_loop loop(*dc); | ||||
| 	divemode = loop.next(bottom_time); | ||||
| 	gas = get_cylinder(dive, current_cylinder)->gasmix; | ||||
| 	gas = dive->get_cylinder(current_cylinder)->gasmix; | ||||
| 
 | ||||
| 	po2 = sample.setpoint.mbar; | ||||
| 	depth = sample.depth.mm; | ||||
|  | @ -768,11 +768,11 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 		// How long can we stay at the current depth and still directly ascent to the surface?
 | ||||
| 		do { | ||||
| 			add_segment(ds, dive->depth_to_bar(depth), | ||||
| 				    get_cylinder(dive, current_cylinder)->gasmix, | ||||
| 				    dive->get_cylinder(current_cylinder)->gasmix, | ||||
| 				    timestep, po2, divemode, prefs.bottomsac, true); | ||||
| 			update_cylinder_pressure(dive, depth, depth, timestep, prefs.bottomsac, get_cylinder(dive, current_cylinder), false, divemode); | ||||
| 			update_cylinder_pressure(dive, depth, depth, timestep, prefs.bottomsac, dive->get_cylinder(current_cylinder), false, divemode); | ||||
| 			clock += timestep; | ||||
| 		} while (trial_ascent(ds, 0, depth, 0, avg_depth, bottom_time, get_cylinder(dive, current_cylinder)->gasmix, | ||||
| 		} while (trial_ascent(ds, 0, depth, 0, avg_depth, bottom_time, dive->get_cylinder(current_cylinder)->gasmix, | ||||
| 				      po2, diveplan->surface_pressure / 1000.0, dive, divemode) && | ||||
| 			 enough_gas(dive, current_cylinder) && clock < 6 * 3600); | ||||
| 
 | ||||
|  | @ -780,7 +780,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 		// In the best of all worlds, we would roll back also the last add_segment in terms of caching deco state, but
 | ||||
| 		// let's ignore that since for the eventual ascent in recreational mode, nobody looks at the ceiling anymore,
 | ||||
| 		// so we don't really have to compute the deco state.
 | ||||
| 		update_cylinder_pressure(dive, depth, depth, -timestep, prefs.bottomsac, get_cylinder(dive, current_cylinder), false, divemode); | ||||
| 		update_cylinder_pressure(dive, depth, depth, -timestep, prefs.bottomsac, dive->get_cylinder(current_cylinder), false, divemode); | ||||
| 		clock -= timestep; | ||||
| 		plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, true, divemode); | ||||
| 		previous_point_time = clock; | ||||
|  | @ -816,7 +816,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 
 | ||||
| 	if (best_first_ascend_cylinder != -1 && best_first_ascend_cylinder != current_cylinder) { | ||||
| 		current_cylinder = best_first_ascend_cylinder; | ||||
| 		gas = get_cylinder(dive, current_cylinder)->gasmix; | ||||
| 		gas = dive->get_cylinder(current_cylinder)->gasmix; | ||||
| 
 | ||||
| #if DEBUG_PLAN & 16 | ||||
| 		printf("switch to gas %d (%d/%d) @ %5.2lfm\n", best_first_ascend_cylinder, | ||||
|  | @ -831,7 +831,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 		po2 = 0; | ||||
| 		int bailoutsegment = std::max(prefs.min_switch_duration, 60 * prefs.problemsolvingtime); | ||||
| 		add_segment(ds, dive->depth_to_bar(depth), | ||||
| 			get_cylinder(dive, current_cylinder)->gasmix, | ||||
| 			dive->get_cylinder(current_cylinder)->gasmix, | ||||
| 			bailoutsegment, po2, divemode, prefs.bottomsac, true); | ||||
| 		plan_add_segment(diveplan, bailoutsegment, depth, current_cylinder, po2, false, divemode); | ||||
| 		bottom_time += bailoutsegment; | ||||
|  | @ -871,7 +871,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 		last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time); | ||||
| 		/* Always prefer the best_first_ascend_cylinder if it has the right gasmix.
 | ||||
| 		 * Otherwise take first cylinder from list with rightgasmix  */ | ||||
| 		if (best_first_ascend_cylinder != -1 && same_gasmix(gas, get_cylinder(dive, best_first_ascend_cylinder)->gasmix)) | ||||
| 		if (best_first_ascend_cylinder != -1 && same_gasmix(gas, dive->get_cylinder(best_first_ascend_cylinder)->gasmix)) | ||||
| 			current_cylinder = best_first_ascend_cylinder; | ||||
| 		else | ||||
| 			current_cylinder = get_gasidx(dive, gas); | ||||
|  | @ -896,7 +896,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 					deltad = depth - stoplevels[stopidx]; | ||||
| 
 | ||||
| 				add_segment(ds, dive->depth_to_bar(depth), | ||||
| 								get_cylinder(dive, current_cylinder)->gasmix, | ||||
| 								dive->get_cylinder(current_cylinder)->gasmix, | ||||
| 								base_timestep, po2, divemode, prefs.decosac, true); | ||||
| 				last_segment_min_switch = false; | ||||
| 				clock += base_timestep; | ||||
|  | @ -921,7 +921,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 				if (current_cylinder != gaschanges[gi].gasidx) { | ||||
| 					if (!prefs.switch_at_req_stop || | ||||
| 							!trial_ascent(ds, 0, depth, stoplevels[stopidx - 1], avg_depth, bottom_time, | ||||
| 							get_cylinder(dive, current_cylinder)->gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode) || get_o2(get_cylinder(dive, current_cylinder)->gasmix) < 160) { | ||||
| 							dive->get_cylinder(current_cylinder)->gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode) || get_o2(dive->get_cylinder(current_cylinder)->gasmix) < 160) { | ||||
| 						if (is_final_plan) | ||||
| 							plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false, divemode); | ||||
| 						stopping = true; | ||||
|  | @ -930,14 +930,14 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 						if (divemode == CCR) | ||||
| 							po2 = setpoint_change(dive, current_cylinder); | ||||
| #if DEBUG_PLAN & 16 | ||||
| 						gas = get_cylinder(dive, current_cylinder)->gasmix; | ||||
| 						gas = dive->get_cylinder(current_cylinder)->gasmix; | ||||
| 						printf("switch to gas %d (%d/%d) @ %5.2lfm\n", gaschanges[gi].gasidx, | ||||
| 							(get_o2(&gas) + 5) / 10, (get_he(&gas) + 5) / 10, gaschanges[gi].depth / 1000.0); | ||||
| #endif | ||||
| 						/* Stop for the minimum duration to switch gas unless we switch to o2 */ | ||||
| 						if (!last_segment_min_switch && get_o2(get_cylinder(dive, current_cylinder)->gasmix) != 1000) { | ||||
| 						if (!last_segment_min_switch && get_o2(dive->get_cylinder(current_cylinder)->gasmix) != 1000) { | ||||
| 							add_segment(ds, dive->depth_to_bar(depth), | ||||
| 								get_cylinder(dive, current_cylinder)->gasmix, | ||||
| 								dive->get_cylinder(current_cylinder)->gasmix, | ||||
| 								prefs.min_switch_duration, po2, divemode, prefs.decosac, true); | ||||
| 							clock += prefs.min_switch_duration; | ||||
| 							last_segment_min_switch = true; | ||||
|  | @ -957,7 +957,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 			while (1) { | ||||
| 				/* Check if ascending to next stop is clear, go back and wait if we hit the ceiling on the way */ | ||||
| 				if (trial_ascent(ds, 0, depth, stoplevels[stopidx], avg_depth, bottom_time, | ||||
| 						get_cylinder(dive, current_cylinder)->gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode)) { | ||||
| 						dive->get_cylinder(current_cylinder)->gasmix, po2, diveplan->surface_pressure / 1000.0, dive, divemode)) { | ||||
| 					decostoptable[decostopcounter].depth = depth; | ||||
| 					decostoptable[decostopcounter].time = 0; | ||||
| 					decostopcounter++; | ||||
|  | @ -986,14 +986,14 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 					if (divemode == CCR) | ||||
| 						po2 = setpoint_change(dive, current_cylinder); | ||||
| #if DEBUG_PLAN & 16 | ||||
| 					gas = get_cylinder(dive, current_cylinder)->gasmix; | ||||
| 					gas = dive->get_cylinder(current_cylinder)->gasmix; | ||||
| 					printf("switch to gas %d (%d/%d) @ %5.2lfm\n", gaschanges[gi + 1].gasidx, | ||||
| 						(get_o2(&gas) + 5) / 10, (get_he(&gas) + 5) / 10, gaschanges[gi + 1].depth / 1000.0); | ||||
| #endif | ||||
| 					/* Stop for the minimum duration to switch gas unless we switch to o2 */ | ||||
| 					if (!last_segment_min_switch && get_o2(get_cylinder(dive, current_cylinder)->gasmix) != 1000) { | ||||
| 					if (!last_segment_min_switch && get_o2(dive->get_cylinder(current_cylinder)->gasmix) != 1000) { | ||||
| 						add_segment(ds, dive->depth_to_bar(depth), | ||||
| 							get_cylinder(dive, current_cylinder)->gasmix, | ||||
| 							dive->get_cylinder(current_cylinder)->gasmix, | ||||
| 							prefs.min_switch_duration, po2, divemode, prefs.decosac, true); | ||||
| 						clock += prefs.min_switch_duration; | ||||
| 					} | ||||
|  | @ -1001,7 +1001,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 				} | ||||
| 
 | ||||
| 				int new_clock = wait_until(ds, dive, clock, clock, laststoptime * 2 + 1, timestep, depth, stoplevels[stopidx], avg_depth, | ||||
| 					bottom_time, get_cylinder(dive, current_cylinder)->gasmix, po2, diveplan->surface_pressure / 1000.0, divemode); | ||||
| 					bottom_time, dive->get_cylinder(current_cylinder)->gasmix, po2, diveplan->surface_pressure / 1000.0, divemode); | ||||
| 				laststoptime = new_clock - clock; | ||||
| 				/* Finish infinite deco */ | ||||
| 				if (laststoptime >= 48 * 3600 && depth >= 6000) { | ||||
|  | @ -1016,12 +1016,12 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 					 * backgas.  This could be customized if there were demand. | ||||
| 					 */ | ||||
| 					if (break_cylinder == -1) { | ||||
| 						if (best_first_ascend_cylinder != -1 && get_o2(get_cylinder(dive, best_first_ascend_cylinder)->gasmix) <= 320) | ||||
| 						if (best_first_ascend_cylinder != -1 && get_o2(dive->get_cylinder(best_first_ascend_cylinder)->gasmix) <= 320) | ||||
| 							break_cylinder = best_first_ascend_cylinder; | ||||
| 						else | ||||
| 							break_cylinder = 0; | ||||
| 					} | ||||
| 					if (get_o2(get_cylinder(dive, current_cylinder)->gasmix) == 1000) { | ||||
| 					if (get_o2(dive->get_cylinder(current_cylinder)->gasmix) == 1000) { | ||||
| 						if (laststoptime >= 12 * 60) { | ||||
| 							laststoptime = 12 * 60; | ||||
| 							new_clock = clock + laststoptime; | ||||
|  | @ -1046,7 +1046,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				add_segment(ds, dive->depth_to_bar(depth), get_cylinder(dive, stop_cylinder)->gasmix, | ||||
| 				add_segment(ds, dive->depth_to_bar(depth), dive->get_cylinder(stop_cylinder)->gasmix, | ||||
| 					    laststoptime, po2, divemode, prefs.decosac, true); | ||||
| 				last_segment_min_switch = false; | ||||
| 				decostoptable[decostopcounter].depth = depth; | ||||
|  |  | |||
|  | @ -191,13 +191,13 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d | |||
| 		nextdp = dp->next; | ||||
| 		if (dp->time == 0) | ||||
| 			continue; | ||||
| 		gasmix = get_cylinder(dive, dp->cylinderid)->gasmix; | ||||
| 		gasmix = dive->get_cylinder(dp->cylinderid)->gasmix; | ||||
| 		depthvalue = get_depth_units(dp->depth.mm, &decimals, &depth_unit); | ||||
| 		/* analyze the dive points ahead */ | ||||
| 		while (nextdp && nextdp->time == 0) | ||||
| 			nextdp = nextdp->next; | ||||
| 		if (nextdp) | ||||
| 			newgasmix = get_cylinder(dive, nextdp->cylinderid)->gasmix; | ||||
| 			newgasmix = dive->get_cylinder(nextdp->cylinderid)->gasmix; | ||||
| 		gaschange_after = (nextdp && (gasmix_distance(gasmix, newgasmix))); | ||||
| 		gaschange_before =  (gasmix_distance(lastprintgasmix, gasmix)); | ||||
| 		rebreatherchange_after = (nextdp && (dp->setpoint != nextdp->setpoint || dp->divemode != nextdp->divemode)); | ||||
|  | @ -577,7 +577,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d | |||
| 			while (dp) { | ||||
| 				if (dp->time != 0) { | ||||
| 					std::string temp; | ||||
| 					struct gasmix gasmix = get_cylinder(dive, dp->cylinderid)->gasmix; | ||||
| 					struct gasmix gasmix = dive->get_cylinder(dp->cylinderid)->gasmix; | ||||
| 
 | ||||
| 					divemode_t current_divemode = loop.next(dp->time); | ||||
| 					amb = dive->depth_to_atm(dp->depth.mm); | ||||
|  |  | |||
|  | @ -126,7 +126,7 @@ static int get_local_sac(struct plot_info &pi, int idx1, int idx2, struct dive * | |||
| 	depth = (entry1.depth + entry2.depth) / 2; | ||||
| 	atm = dive->depth_to_atm(depth); | ||||
| 
 | ||||
| 	cyl = get_cylinder(dive, index); | ||||
| 	cyl = dive->get_cylinder(index); | ||||
| 
 | ||||
| 	airuse = gas_volume(cyl, a) - gas_volume(cyl, b); | ||||
| 
 | ||||
|  | @ -193,35 +193,6 @@ static void analyze_plot_info(struct plot_info &pi) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * If the event has an explicit cylinder index, | ||||
|  * we return that. If it doesn't, we return the best | ||||
|  * match based on the gasmix. | ||||
|  * | ||||
|  * Some dive computers give cylinder indices, some | ||||
|  * give just the gas mix. | ||||
|  */ | ||||
| int get_cylinder_index(const struct dive *dive, const struct event &ev) | ||||
| { | ||||
| 	int best; | ||||
| 	struct gasmix mix; | ||||
| 
 | ||||
| 	if (ev.gas.index >= 0) | ||||
| 		return ev.gas.index; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * This should no longer happen! | ||||
| 	 * | ||||
| 	 * We now match up gas change events with their cylinders at dive | ||||
| 	 * event fixup time. | ||||
| 	 */ | ||||
| 	report_info("Still looking up cylinder based on gas mix in get_cylinder_index()!"); | ||||
| 
 | ||||
| 	mix = get_gasmix_from_event(dive, ev); | ||||
| 	best = find_best_gasmix_match(mix, dive->cylinders); | ||||
| 	return best < 0 ? 0 : best; | ||||
| } | ||||
| 
 | ||||
| static size_t set_setpoint(struct plot_info &pi, size_t i, int setpoint, int end) | ||||
| { | ||||
| 	while (i < pi.entry.size()) { | ||||
|  | @ -508,7 +479,7 @@ static int sac_between(const struct dive *dive, const struct plot_info &pi, int | |||
| 
 | ||||
| 		a.mbar = get_plot_pressure(pi, first, i); | ||||
| 		b.mbar = get_plot_pressure(pi, last, i); | ||||
| 		const cylinder_t *cyl = get_cylinder(dive, i); | ||||
| 		const cylinder_t *cyl = dive->get_cylinder(i); | ||||
| 		int cyluse = gas_volume(cyl, a) - gas_volume(cyl, b); | ||||
| 		if (cyluse > 0) | ||||
| 			airuse += cyluse; | ||||
|  | @ -704,7 +675,7 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive | |||
| 	std::vector<int> first(num_cyl, 0); | ||||
| 	std::vector<int> last(num_cyl, INT_MAX); | ||||
| 
 | ||||
| 	int prev = explicit_first_cylinder(dive, dc); | ||||
| 	int prev = dive->explicit_first_cylinder(dc); | ||||
| 	prev = prev >= 0 ? prev : 0; | ||||
| 	seen[prev] = 1; | ||||
| 
 | ||||
|  | @ -735,7 +706,7 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive | |||
| 	// Fill in "seen[]" array - mark cylinders we're not interested
 | ||||
| 	// in as negative.
 | ||||
| 	for (int i = 0; i < pi.nr_cylinders; i++) { | ||||
| 		const cylinder_t *cyl = get_cylinder(dive, i); | ||||
| 		const cylinder_t *cyl = dive->get_cylinder(i); | ||||
| 		int start = cyl->start.mbar; | ||||
| 		int end = cyl->end.mbar; | ||||
| 
 | ||||
|  | @ -756,7 +727,7 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive | |||
| 
 | ||||
| 		/* If it's only mentioned by other dc's, ignore it */ | ||||
| 		for (auto &secondary: dive->dcs) { | ||||
| 			if (has_gaschange_event(dive, &secondary, i)) { | ||||
| 			if (dive->has_gaschange_event(&secondary, i)) { | ||||
| 				seen[i] = -1; | ||||
| 				break; | ||||
| 			} | ||||
|  | @ -765,7 +736,7 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive | |||
| 
 | ||||
| 	for (int i = 0; i < pi.nr_cylinders; i++) { | ||||
| 		if (seen[i] >= 0) { | ||||
| 			const cylinder_t *cyl = get_cylinder(dive, i); | ||||
| 			const cylinder_t *cyl = dive->get_cylinder(i); | ||||
| 
 | ||||
| 			add_plot_pressure(pi, first[i], i, cyl->start); | ||||
| 			add_plot_pressure(pi, last[i], i, cyl->end); | ||||
|  | @ -1306,7 +1277,7 @@ static std::vector<std::string> plot_string(const struct dive *d, const struct p | |||
| 		int mbar = get_plot_pressure(pi, idx, cyl); | ||||
| 		if (!mbar) | ||||
| 			continue; | ||||
| 		struct gasmix mix = get_cylinder(d, cyl)->gasmix; | ||||
| 		struct gasmix mix = d->get_cylinder(cyl)->gasmix; | ||||
| 		pressurevalue = get_pressure_units(mbar, &pressure_unit); | ||||
| 		res.push_back(casprintf_loc(translate("gettextFromC", "P: %d%s (%s)"), pressurevalue, pressure_unit, gasname(mix))); | ||||
| 	} | ||||
|  | @ -1531,7 +1502,7 @@ std::vector<std::string> compare_samples(const struct dive *d, const struct plot | |||
| 				if (last_pressures[cylinder_index]) { | ||||
| 					bar_used[cylinder_index] += last_pressures[cylinder_index] - next_pressure; | ||||
| 
 | ||||
| 					const cylinder_t *cyl = get_cylinder(d, cylinder_index); | ||||
| 					const cylinder_t *cyl = d->get_cylinder(cylinder_index); | ||||
| 
 | ||||
| 					volumes_used[cylinder_index] += gas_volume(cyl, (pressure_t){ last_pressures[cylinder_index] }) - gas_volume(cyl, (pressure_t){ next_pressure }); | ||||
| 				} | ||||
|  | @ -1584,7 +1555,7 @@ std::vector<std::string> compare_samples(const struct dive *d, const struct plot | |||
| 			total_bar_used += bar_used[cylinder_index]; | ||||
| 			total_volume_used += volumes_used[cylinder_index]; | ||||
| 
 | ||||
| 			const cylinder_t *cyl = get_cylinder(d, cylinder_index); | ||||
| 			const cylinder_t *cyl = d->get_cylinder(cylinder_index); | ||||
| 			if (cyl->type.size.mliter) { | ||||
| 				if (cylinder_volume.mliter && cylinder_volume.mliter != cyl->type.size.mliter) { | ||||
| 					cylindersizes_are_identical = false; | ||||
|  |  | |||
|  | @ -351,7 +351,7 @@ QVector<QPair<QString, int>> selectedDivesGasUsed() | |||
| 		std::vector<volume_t> diveGases = get_gas_used(d); | ||||
| 		for (size_t j = 0; j < d->cylinders.size(); j++) { | ||||
| 			if (diveGases[j].mliter) { | ||||
| 				QString gasName = gasname(get_cylinder(d, j)->gasmix); | ||||
| 				QString gasName = gasname(d->get_cylinder(j)->gasmix); | ||||
| 				gasUsed[gasName] += diveGases[j].mliter; | ||||
| 			} | ||||
| 		} | ||||
|  |  | |||
|  | @ -385,7 +385,7 @@ static void save_one_event(struct membuffer *b, const struct dive &dive, const s | |||
| 		show_index(b, ev.value, "value=", ""); | ||||
| 	show_utf8(b, " name=", ev.name.c_str(), ""); | ||||
| 	if (ev.is_gaschange()) { | ||||
| 		struct gasmix mix = get_gasmix_from_event(&dive, ev); | ||||
| 		struct gasmix mix = dive.get_gasmix_from_event(ev); | ||||
| 		if (ev.gas.index >= 0) | ||||
| 			show_integer(b, ev.gas.index, "cylinder=", ""); | ||||
| 		put_gasmix(b, mix); | ||||
|  |  | |||
|  | @ -352,7 +352,7 @@ static void save_one_event(struct membuffer *b, const struct dive &dive, const s | |||
| 		show_index(b, ev.value, "value='", "'"); | ||||
| 	show_utf8(b, ev.name.c_str(), " name='", "'", 1); | ||||
| 	if (ev.is_gaschange()) { | ||||
| 		struct gasmix mix = get_gasmix_from_event(&dive, ev); | ||||
| 		struct gasmix mix = dive.get_gasmix_from_event(ev); | ||||
| 		if (ev.gas.index >= 0) | ||||
| 			show_integer(b, ev.gas.index, "cylinder='", "'"); | ||||
| 		put_gasmix(b, mix); | ||||
|  |  | |||
|  | @ -249,51 +249,6 @@ stats_t calculate_stats_selected() | |||
| 
 | ||||
| #define SOME_GAS 5000 // 5bar drop in cylinder pressure makes cylinder used
 | ||||
| 
 | ||||
| bool has_gaschange_event(const struct dive *dive, const struct divecomputer *dc, int idx) | ||||
| { | ||||
| 	bool first_gas_explicit = false; | ||||
| 	event_loop loop("gaschange"); | ||||
| 	while (auto event = loop.next(*dc)) { | ||||
| 		if (!dc->samples.empty() && (event->time.seconds == 0 || | ||||
| 				   (dc->samples[0].time.seconds == event->time.seconds))) | ||||
| 			first_gas_explicit = true; | ||||
| 		if (get_cylinder_index(dive, *event) == idx) | ||||
| 			return true; | ||||
| 	} | ||||
| 	return !first_gas_explicit && idx == 0; | ||||
| } | ||||
| 
 | ||||
| bool is_cylinder_used(const struct dive *dive, int idx) | ||||
| { | ||||
| 	if (idx < 0 || static_cast<size_t>(idx) >= dive->cylinders.size()) | ||||
| 		return false; | ||||
| 
 | ||||
| 	const cylinder_t &cyl = dive->cylinders[idx]; | ||||
| 	if ((cyl.start.mbar - cyl.end.mbar) > SOME_GAS) | ||||
| 		return true; | ||||
| 
 | ||||
| 	if ((cyl.sample_start.mbar - cyl.sample_end.mbar) > SOME_GAS) | ||||
| 		return true; | ||||
| 
 | ||||
| 	for (auto &dc: dive->dcs) { | ||||
| 		if (has_gaschange_event(dive, &dc, idx)) | ||||
| 			return true; | ||||
| 		else if (dc.divemode == CCR && idx == get_cylinder_idx_by_use(dive, OXYGEN)) | ||||
| 			return true; | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| bool is_cylinder_prot(const struct dive *dive, int idx) | ||||
| { | ||||
| 	if (idx < 0 || static_cast<size_t>(idx) >= dive->cylinders.size()) | ||||
| 		return false; | ||||
| 
 | ||||
| 	return std::any_of(dive->dcs.begin(), dive->dcs.end(), | ||||
| 			   [dive, idx](auto &dc) | ||||
| 			   { return has_gaschange_event(dive, &dc, idx); }); | ||||
| } | ||||
| 
 | ||||
| /* Returns a vector with dive->cylinders.size() entries */ | ||||
| std::vector<volume_t> get_gas_used(struct dive *dive) | ||||
| { | ||||
|  | @ -334,7 +289,7 @@ std::pair<volume_t, volume_t> selected_dives_gas_parts() | |||
| 		int j = 0; | ||||
| 		for (auto &gas: get_gas_used(d.get())) { | ||||
| 			if (gas.mliter) { | ||||
| 				auto [o2, he] = get_gas_parts(get_cylinder(d.get(), j)->gasmix, gas, O2_IN_AIR); | ||||
| 				auto [o2, he] = get_gas_parts(d->get_cylinder(j)->gasmix, gas, O2_IN_AIR); | ||||
| 				o2_tot.mliter += o2.mliter; | ||||
| 				he_tot.mliter += he.mliter; | ||||
| 			} | ||||
|  |  | |||
|  | @ -79,7 +79,7 @@ QStringList formatGetCylinder(const dive *d) | |||
| { | ||||
| 	QStringList getCylinder; | ||||
| 	for (auto [i, cyl]: enumerated_range(d->cylinders)) { | ||||
| 		if (is_cylinder_used(d, i)) | ||||
| 		if (d->is_cylinder_used(i)) | ||||
| 			getCylinder << QString::fromStdString(cyl.type.description); | ||||
| 	} | ||||
| 	return getCylinder; | ||||
|  | @ -89,7 +89,7 @@ QStringList formatStartPressure(const dive *d) | |||
| { | ||||
| 	QStringList startPressure; | ||||
| 	for (auto [i, cyl]: enumerated_range(d->cylinders)) { | ||||
| 		if (is_cylinder_used(d, i)) | ||||
| 		if (d->is_cylinder_used(i)) | ||||
| 			startPressure << getPressures(cyl, START_PRESSURE); | ||||
| 	} | ||||
| 	return startPressure; | ||||
|  | @ -99,7 +99,7 @@ QStringList formatEndPressure(const dive *d) | |||
| { | ||||
| 	QStringList endPressure; | ||||
| 	for (auto [i, cyl]: enumerated_range(d->cylinders)) { | ||||
| 		if (is_cylinder_used(d, i)) | ||||
| 		if (d->is_cylinder_used(i)) | ||||
| 			endPressure << getPressures(cyl, END_PRESSURE); | ||||
| 	} | ||||
| 	return endPressure; | ||||
|  | @ -109,7 +109,7 @@ QStringList formatFirstGas(const dive *d) | |||
| { | ||||
| 	QStringList gas; | ||||
| 	for (auto [i, cyl]: enumerated_range(d->cylinders)) { | ||||
| 		if (is_cylinder_used(d, i)) | ||||
| 		if (d->is_cylinder_used(i)) | ||||
| 			gas << get_gas_string(cyl.gasmix); | ||||
| 	} | ||||
| 	return gas; | ||||
|  | @ -174,7 +174,7 @@ QString formatGas(const dive *d) | |||
| 	 */ | ||||
| 	QString gases; | ||||
| 	for (auto [i, cyl]: enumerated_range(d->cylinders)) { | ||||
| 		if (!is_cylinder_used(d, i)) | ||||
| 		if (!d->is_cylinder_used(i)) | ||||
| 			continue; | ||||
| 		QString gas = QString::fromStdString(cyl.type.description); | ||||
| 		if (!gas.isEmpty()) | ||||
|  |  | |||
|  | @ -346,7 +346,7 @@ void DiveComponentSelection::buttonClicked(QAbstractButton *button) | |||
| 		if (what->cylinders) { | ||||
| 			text << tr("Cylinders:\n"); | ||||
| 			for (auto [idx, cyl]: enumerated_range(current_dive->cylinders)) { | ||||
| 				if (is_cylinder_used(current_dive, idx)) | ||||
| 				if (current_dive->is_cylinder_used(idx)) | ||||
| 					text << QString::fromStdString(cyl.type.description) << " " << gasname(cyl.gasmix) << "\n"; | ||||
| 			} | ||||
| 		} | ||||
|  |  | |||
|  | @ -134,12 +134,12 @@ void TabDiveInformation::updateProfile() | |||
| 	QString gaslist, SACs, separator; | ||||
| 
 | ||||
| 	for (size_t i = 0; i < currentDive->cylinders.size(); i++) { | ||||
| 		if (!is_cylinder_used(currentDive, i)) | ||||
| 		if (!currentDive->is_cylinder_used(i)) | ||||
| 			continue; | ||||
| 		gaslist.append(separator); volumes.append(separator); SACs.append(separator); | ||||
| 		separator = "\n"; | ||||
| 
 | ||||
| 		gaslist.append(gasname(get_cylinder(currentDive, i)->gasmix)); | ||||
| 		gaslist.append(gasname(currentDive->get_cylinder(i)->gasmix)); | ||||
| 		if (!gases[i].mliter) | ||||
| 			continue; | ||||
| 		volumes.append(get_volume_string(gases[i], true)); | ||||
|  |  | |||
|  | @ -1242,7 +1242,7 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt | |||
| 	if (formatStartPressure(d) != startpressure || formatEndPressure(d) != endpressure) { | ||||
| 		diveChanged = true; | ||||
| 		for ( int i = 0, j = 0 ; j < startpressure.length() && j < endpressure.length() ; i++ ) { | ||||
| 			if (state != "add" && !is_cylinder_used(d, i)) | ||||
| 			if (state != "add" && !d->is_cylinder_used(i)) | ||||
| 				continue; | ||||
| 
 | ||||
| 			cylinder_t *cyl = get_or_create_cylinder(d, i); | ||||
|  | @ -1257,7 +1257,7 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt | |||
| 	// gasmix for first cylinder
 | ||||
| 	if (formatFirstGas(d) != gasmix) { | ||||
| 		for ( int i = 0, j = 0 ; j < gasmix.length() ; i++ ) { | ||||
| 			if (state != "add" && !is_cylinder_used(d, i)) | ||||
| 			if (state != "add" && !d->is_cylinder_used(i)) | ||||
| 				continue; | ||||
| 
 | ||||
| 			int o2 = parseGasMixO2(gasmix[j]); | ||||
|  | @ -1268,7 +1268,7 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt | |||
| 				o2 + he <= 1000) { | ||||
| 				diveChanged = true; | ||||
| 				get_or_create_cylinder(d, i)->gasmix.o2.permille = o2; | ||||
| 				get_cylinder(d, i)->gasmix.he.permille = he; | ||||
| 				d->get_cylinder(i)->gasmix.he.permille = he; | ||||
| 			} | ||||
| 			j++; | ||||
| 		} | ||||
|  | @ -1278,7 +1278,7 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt | |||
| 		diveChanged = true; | ||||
| 		int size = 0, wp = 0, j = 0, k = 0; | ||||
| 		for (j = 0; k < usedCylinder.length(); j++) { | ||||
| 			if (state != "add" && !is_cylinder_used(d, j)) | ||||
| 			if (state != "add" && !d->is_cylinder_used(j)) | ||||
| 				continue; | ||||
| 
 | ||||
| 			for (const tank_info &ti: tank_info_table) { | ||||
|  | @ -1294,8 +1294,8 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt | |||
| 				} | ||||
| 			} | ||||
| 			get_or_create_cylinder(d, j)->type.description = usedCylinder[k].toStdString(); | ||||
| 			get_cylinder(d, j)->type.size.mliter = size; | ||||
| 			get_cylinder(d, j)->type.workingpressure.mbar = wp; | ||||
| 			d->get_cylinder(j)->type.size.mliter = size; | ||||
| 			d->get_cylinder(j)->type.workingpressure.mbar = wp; | ||||
| 			k++; | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -51,7 +51,7 @@ void DiveEventItem::setupPixmap(struct gasmix lastgasmix, const DivePixmaps &pix | |||
| 		setPixmap(pixmaps.bookmark); | ||||
| 		setOffset(QPointF(0.0, -pixmap().height())); | ||||
| 	} else if (ev.is_gaschange()) { | ||||
| 		struct gasmix mix = get_gasmix_from_event(dive, ev); | ||||
| 		struct gasmix mix = dive->get_gasmix_from_event(ev); | ||||
| 		struct icd_data icd_data; | ||||
| 		bool icd = isobaric_counterdiffusion(lastgasmix, mix, &icd_data); | ||||
| 		if (mix.he.permille) { | ||||
|  | @ -123,7 +123,7 @@ void DiveEventItem::setupToolTipString(struct gasmix lastgasmix) | |||
| 
 | ||||
| 	if (ev.is_gaschange()) { | ||||
| 		struct icd_data icd_data; | ||||
| 		struct gasmix mix = get_gasmix_from_event(dive, ev); | ||||
| 		struct gasmix mix = dive->get_gasmix_from_event(ev); | ||||
| 		name += ": "; | ||||
| 		name += gasname(mix); | ||||
| 
 | ||||
|  |  | |||
|  | @ -602,9 +602,7 @@ void DiveGasPressureItem::replot(const dive *d, int fromIn, int toIn, bool in_pl | |||
| 
 | ||||
| 	bool showDescriptions = false; | ||||
| 	for (int cyl = 0; cyl < pInfo.nr_cylinders; cyl++) { | ||||
| 		const cylinder_t *c = get_cylinder(d, cyl); | ||||
| 		if (!c) | ||||
| 			continue; | ||||
| 		const cylinder_t *c = d->get_cylinder(cyl); | ||||
| 		showDescriptions = showDescriptions || (c && same_gasmix_cylinder(*c, cyl, d, true) != -1); | ||||
| 		if (act_segments[cyl].polygon.empty()) | ||||
| 			continue; | ||||
|  | @ -634,7 +632,7 @@ void DiveGasPressureItem::replot(const dive *d, int fromIn, int toIn, bool in_pl | |||
| 
 | ||||
| 		// For each cylinder, on right hand side of the curve, write cylinder pressure
 | ||||
| 		double x_offset = plotPressureValue(segment.last.pressure, segment.last.time, Qt::AlignTop | Qt::AlignLeft, y_offset) + 2; | ||||
| 		plotGasValue(segment.last.pressure, segment.last.time, get_cylinder(d, segment.cyl), Qt::AlignTop | Qt::AlignLeft, x_offset, y_offset, showDescriptions); | ||||
| 		plotGasValue(segment.last.pressure, segment.last.time, d->get_cylinder(segment.cyl), Qt::AlignTop | Qt::AlignLeft, x_offset, y_offset, showDescriptions); | ||||
| 
 | ||||
| 		/* Alternate alignment as we see cylinder use.. */ | ||||
| 		startAlignVar ^= Qt::AlignTop | Qt::AlignBottom; | ||||
|  |  | |||
|  | @ -551,7 +551,7 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM | |||
| 	// while all other items are up there on the constructor.
 | ||||
| 	qDeleteAll(eventItems); | ||||
| 	eventItems.clear(); | ||||
| 	struct gasmix lastgasmix = get_gasmix_at_time(*d, *currentdc, duration_t{1}); | ||||
| 	struct gasmix lastgasmix = d->get_gasmix_at_time(*currentdc, duration_t{1}); | ||||
| 
 | ||||
| 	for (auto [idx, event]: enumerated_range(currentdc->events)) { | ||||
| 		// if print mode is selected only draw headings, SP change, gas events or bookmark event
 | ||||
|  | @ -571,7 +571,7 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM | |||
| 			eventItems.push_back(item); | ||||
| 		} | ||||
| 		if (event.is_gaschange()) | ||||
| 			lastgasmix = get_gasmix_from_event(d, event); | ||||
| 			lastgasmix = d->get_gasmix_from_event(event); | ||||
| 	} | ||||
| 
 | ||||
| 	QString dcText = QString::fromStdString(get_dc_nickname(currentdc)); | ||||
|  |  | |||
|  | @ -614,7 +614,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event) | |||
| 			if (gasChangeIdx < plotInfo.nr - 1) { | ||||
| 				int newGasIdx = gasChangeIdx + 1; | ||||
| 				const struct plot_data &newGasEntry = plotInfo.entry[newGasIdx]; | ||||
| 				if (get_plot_sensor_pressure(&plotInfo, gasChangeIdx) == 0 || get_cylinder(d, gasChangeEntry->sensor[0])->sample_start.mbar == 0) { | ||||
| 				if (get_plot_sensor_pressure(&plotInfo, gasChangeIdx) == 0 || d->get_cylinder(gasChangeEntry->sensor[0])->sample_start.mbar == 0) { | ||||
| 					// if we have no sensorpressure or if we have no pressure from samples we can assume that
 | ||||
| 					// we only have interpolated pressure (the pressure in the entry may be stored in the sensor
 | ||||
| 					// pressure field if this is the first or last entry for this tank... see details in gaspressures.c
 | ||||
|  | @ -623,7 +623,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event) | |||
| 					QAction *adjustOldPressure = m.addAction(tr("Adjust pressure of cyl. %1 (currently interpolated as %2)") | ||||
| 										 .arg(gasChangeEntry->sensor[0] + 1).arg(get_pressure_string(pressure))); | ||||
| 				} | ||||
| 				if (get_plot_sensor_pressure(&plotInfo, newGasIdx) == 0 || get_cylinder(d, newGasEntry->sensor[0])->sample_start.mbar == 0) { | ||||
| 				if (get_plot_sensor_pressure(&plotInfo, newGasIdx) == 0 || d->get_cylinder(newGasEntry->sensor[0])->sample_start.mbar == 0) { | ||||
| 					// we only have interpolated press -- see commend above
 | ||||
| 					pressure_t pressure; | ||||
| 					pressure.mbar = get_plot_interpolated_pressure(&plotInfo, newGasIdx) ? : get_plot_sensor_pressure(&plotInfo, newGasIdx); | ||||
|  | @ -920,7 +920,7 @@ void ProfileWidget2::repositionDiveHandlers() | |||
| 		QPointF pos = line.pointAt(0.5); | ||||
| 		gases[i]->setPos(pos); | ||||
| 		if (datapoint.cylinderid >= 0 && datapoint.cylinderid < static_cast<int>(d->cylinders.size())) | ||||
| 			gases[i]->setText(get_gas_string(get_cylinder(d, datapoint.cylinderid)->gasmix)); | ||||
| 			gases[i]->setText(get_gas_string(d->get_cylinder(datapoint.cylinderid)->gasmix)); | ||||
| 		else | ||||
| 			gases[i]->setText(QString()); | ||||
| 		gases[i]->setVisible(datapoint.entered && | ||||
|  |  | |||
|  | @ -84,14 +84,14 @@ void TankItem::setData(const struct dive *d, const struct divecomputer *dc, int | |||
| 	struct gasmix gasmix = gasmix_invalid; | ||||
| 	const struct event *ev; | ||||
| 	while ((ev = loop.next(*dc)) != nullptr && ev->time.seconds <= plotStartTime) | ||||
| 		gasmix = get_gasmix_from_event(d, *ev); | ||||
| 		gasmix = d->get_gasmix_from_event(*ev); | ||||
| 
 | ||||
| 	// work through all the gas changes and add the rectangle for each gas while it was used
 | ||||
| 	int startTime = plotStartTime; | ||||
| 	while (ev && (int)ev->time.seconds < plotEndTime) { | ||||
| 		createBar(startTime, ev->time.seconds, gasmix); | ||||
| 		startTime = ev->time.seconds; | ||||
| 		gasmix = get_gasmix_from_event(d, *ev); | ||||
| 		gasmix = d->get_gasmix_from_event(*ev); | ||||
| 		ev = loop.next(*dc); | ||||
| 	} | ||||
| 	createBar(startTime, plotEndTime, gasmix); | ||||
|  |  | |||
|  | @ -155,7 +155,7 @@ QVariant CylindersModel::data(const QModelIndex &index, int role) const | |||
| 		return QVariant(); | ||||
| 	} | ||||
| 
 | ||||
| 	const cylinder_t *cyl = index.row() == tempRow ? &tempCyl : get_cylinder(d, index.row()); | ||||
| 	const cylinder_t *cyl = index.row() == tempRow ? &tempCyl : d->get_cylinder(index.row()); | ||||
| 
 | ||||
| 	switch (role) { | ||||
| 	case Qt::BackgroundRole: { | ||||
|  | @ -259,7 +259,7 @@ QVariant CylindersModel::data(const QModelIndex &index, int role) const | |||
| 	case Qt::SizeHintRole: | ||||
| 		if (index.column() == REMOVE) { | ||||
| 			if ((inPlanner && DivePlannerPointsModel::instance()->tankInUse(index.row())) || | ||||
| 				(!inPlanner && is_cylinder_prot(d, index.row()))) { | ||||
| 				(!inPlanner && d->is_cylinder_prot(index.row()))) { | ||||
| 					return trashForbiddenIcon(); | ||||
| 			} | ||||
| 			return trashIcon(); | ||||
|  | @ -269,7 +269,7 @@ QVariant CylindersModel::data(const QModelIndex &index, int role) const | |||
| 		switch (index.column()) { | ||||
| 		case REMOVE: | ||||
| 			if ((inPlanner && DivePlannerPointsModel::instance()->tankInUse(index.row())) || | ||||
| 				(!inPlanner && is_cylinder_prot(d, index.row()))) { | ||||
| 				(!inPlanner && d->is_cylinder_prot(index.row()))) { | ||||
| 					return tr("This gas is in use. Only cylinders that are not used in the dive can be removed."); | ||||
| 			} | ||||
| 			return tr("Clicking here will remove this cylinder."); | ||||
|  | @ -301,7 +301,7 @@ cylinder_t *CylindersModel::cylinderAt(const QModelIndex &index) | |||
| { | ||||
| 	if (!d) | ||||
| 		return nullptr; | ||||
| 	return get_cylinder(d, index.row()); | ||||
| 	return d->get_cylinder(index.row()); | ||||
| } | ||||
| 
 | ||||
| bool CylindersModel::setData(const QModelIndex &index, const QVariant &value, int role) | ||||
|  | @ -364,7 +364,7 @@ bool CylindersModel::setData(const QModelIndex &index, const QVariant &value, in | |||
| 	// First, we make a shallow copy of the old cylinder. Then we modify the fields inside that copy.
 | ||||
| 	// At the end, we either place an EditCylinder undo command (EquipmentTab) or copy the cylinder back (planner).
 | ||||
| 	// Yes, this is not ideal, but the pragmatic thing to do for now.
 | ||||
| 	cylinder_t cyl = *get_cylinder(d, row); | ||||
| 	cylinder_t cyl = *d->get_cylinder(row); | ||||
| 
 | ||||
| 	if (index.column() != TYPE && !changed) | ||||
| 		return false; | ||||
|  | @ -470,7 +470,7 @@ bool CylindersModel::setData(const QModelIndex &index, const QVariant &value, in | |||
| 
 | ||||
| 	if (inPlanner) { | ||||
| 		// In the planner - simply overwrite the cylinder in the dive with the modified cylinder.
 | ||||
| 		*get_cylinder(d, row) = cyl; | ||||
| 		*d->get_cylinder(row) = cyl; | ||||
| 		dataChanged(index, index); | ||||
| 	} else { | ||||
| 		// On the EquipmentTab - place an editCylinder command.
 | ||||
|  | @ -711,7 +711,7 @@ void CylindersModel::initTempCyl(int row) | |||
| 	if (!d || tempRow == row) | ||||
| 		return; | ||||
| 	clearTempCyl(); | ||||
| 	const cylinder_t *cyl = get_cylinder(d, row); | ||||
| 	const cylinder_t *cyl = d->get_cylinder(row); | ||||
| 	if (!cyl) | ||||
| 		return; | ||||
| 
 | ||||
|  | @ -737,7 +737,7 @@ void CylindersModel::commitTempCyl(int row) | |||
| 		return; | ||||
| 	if (row != tempRow) | ||||
| 		return clearTempCyl(); // Huh? We are supposed to commit a different row than the one we stored?
 | ||||
| 	cylinder_t *cyl = get_cylinder(d, tempRow); | ||||
| 	cylinder_t *cyl = d->get_cylinder(tempRow); | ||||
| 	if (!cyl) | ||||
| 		return; | ||||
| 	// Only submit a command if the type changed
 | ||||
|  |  | |||
|  | @ -507,7 +507,7 @@ static void merge_cylinder_info(cylinder_t *src, cylinder_t *dst) | |||
| static void smtk_clean_cylinders(struct dive *d) | ||||
| { | ||||
| 	int i = tanks - 1; | ||||
| 	cylinder_t  *cyl, *base = get_cylinder(d, 0); | ||||
| 	cylinder_t  *cyl, *base = d->get_cylinder(0); | ||||
| 
 | ||||
| 	cyl = base + tanks - 1; | ||||
| 	while (cyl != base) { | ||||
|  |  | |||
|  | @ -768,8 +768,7 @@ void TestPlan::testMultipleGases() | |||
| 	save_dive(stdout, dive, false); | ||||
| #endif | ||||
| 
 | ||||
| 	gasmix gas; | ||||
| 	gas = get_gasmix_at_time(dive, dive.dcs[0], {20 * 60 + 1}); | ||||
| 	gasmix gas = dive.get_gasmix_at_time(dive.dcs[0], {20 * 60 + 1}); | ||||
| 	QCOMPARE(get_o2(gas), 110); | ||||
| 	QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 2480u, 2480u)); | ||||
| } | ||||
|  | @ -963,17 +962,17 @@ void TestPlan::testCcrBailoutGasSelection() | |||
| #endif | ||||
| 
 | ||||
| 	// check diluent used
 | ||||
| 	cylinder_t *cylinder = get_cylinder(&dive, get_cylinderid_at_time(&dive, &dive.dcs[0], { 20 * 60 - 1 })); | ||||
| 	cylinder_t *cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], { 20 * 60 - 1 })); | ||||
| 	QCOMPARE(cylinder->cylinder_use, DILUENT); | ||||
| 	QCOMPARE(get_o2(cylinder->gasmix), 200); | ||||
| 
 | ||||
| 	// check deep bailout used
 | ||||
| 	cylinder = get_cylinder(&dive, get_cylinderid_at_time(&dive, &dive.dcs[0], { 20 * 60 + 1 })); | ||||
| 	cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], { 20 * 60 + 1 })); | ||||
| 	QCOMPARE(cylinder->cylinder_use, OC_GAS); | ||||
| 	QCOMPARE(get_o2(cylinder->gasmix), 190); | ||||
| 
 | ||||
| 	// check shallow bailout used
 | ||||
| 	cylinder = get_cylinder(&dive, get_cylinderid_at_time(&dive, &dive.dcs[0], { 30 * 60 })); | ||||
| 	cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], { 30 * 60 })); | ||||
| 	QCOMPARE(cylinder->cylinder_use, OC_GAS); | ||||
| 	QCOMPARE(get_o2(cylinder->gasmix), 530); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue