mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	Profile: change get_plot_pressure to take index instead of pointer
The goal here is to make it possible to detach the pressure related data from the plot_info structure. Thus, the pressure related data can be allocated independently depending on the number of cylinders per dive. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
		
							parent
							
								
									fbd74c26d6
								
							
						
					
					
						commit
						4724c88533
					
				
					 5 changed files with 80 additions and 71 deletions
				
			
		
							
								
								
									
										122
									
								
								core/profile.c
									
										
									
									
									
								
							
							
						
						
									
										122
									
								
								core/profile.c
									
										
									
									
									
								
							|  | @ -164,13 +164,15 @@ void remember_event(const char *eventname) | |||
| } | ||||
| 
 | ||||
| /* UNUSED! */ | ||||
| static int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive) __attribute__((unused)); | ||||
| static int get_local_sac(struct plot_info *pi, int idx1, int idx2, struct dive *dive) __attribute__((unused)); | ||||
| 
 | ||||
| /* Get local sac-rate (in ml/min) between entry1 and entry2 */ | ||||
| static int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive) | ||||
| static int get_local_sac(struct plot_info *pi, int idx1, int idx2, struct dive *dive) | ||||
| { | ||||
| 	int index = 0; | ||||
| 	cylinder_t *cyl; | ||||
| 	struct plot_data *entry1 = pi->entry + idx1; | ||||
| 	struct plot_data *entry2 = pi->entry + idx2; | ||||
| 	int duration = entry2->sec - entry1->sec; | ||||
| 	int depth, airuse; | ||||
| 	pressure_t a, b; | ||||
|  | @ -178,8 +180,8 @@ static int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, str | |||
| 
 | ||||
| 	if (duration <= 0) | ||||
| 		return 0; | ||||
| 	a.mbar = get_plot_pressure(entry1, 0); | ||||
| 	b.mbar = get_plot_pressure(entry2, 0); | ||||
| 	a.mbar = get_plot_pressure(pi, idx1, 0); | ||||
| 	b.mbar = get_plot_pressure(pi, idx2, 0); | ||||
| 	if (!b.mbar || a.mbar <= b.mbar) | ||||
| 		return 0; | ||||
| 
 | ||||
|  | @ -645,7 +647,7 @@ static void populate_plot_entries(struct dive *dive, struct divecomputer *dc, st | |||
|  * | ||||
|  * Everything in between has a cylinder pressure for at least some of the cylinders. | ||||
|  */ | ||||
| static int sac_between(struct dive *dive, struct plot_data *first, struct plot_data *last, unsigned int gases) | ||||
| static int sac_between(struct dive *dive, struct plot_info *pi, int first, int last, unsigned int gases) | ||||
| { | ||||
| 	int i, airuse; | ||||
| 	double pressuretime; | ||||
|  | @ -663,8 +665,8 @@ static int sac_between(struct dive *dive, struct plot_data *first, struct plot_d | |||
| 		if (!(gases & (1u << i))) | ||||
| 			continue; | ||||
| 
 | ||||
| 		a.mbar = get_plot_pressure(first, i); | ||||
| 		b.mbar = get_plot_pressure(last, i); | ||||
| 		a.mbar = get_plot_pressure(pi, first, i); | ||||
| 		b.mbar = get_plot_pressure(pi, last, i); | ||||
| 		cyl = dive->cylinder + i; | ||||
| 		cyluse = gas_volume(cyl, a) - gas_volume(cyl, b); | ||||
| 		if (cyluse > 0) | ||||
|  | @ -676,8 +678,10 @@ static int sac_between(struct dive *dive, struct plot_data *first, struct plot_d | |||
| 	/* Calculate depthpressure integrated over time */ | ||||
| 	pressuretime = 0.0; | ||||
| 	do { | ||||
| 		int depth = (first[0].depth + first[1].depth) / 2; | ||||
| 		int time = first[1].sec - first[0].sec; | ||||
| 		struct plot_data *entry = pi->entry + first; | ||||
| 		struct plot_data *next = entry + 1; | ||||
| 		int depth = (entry->depth + next->depth) / 2; | ||||
| 		int time = next->sec - entry->sec; | ||||
| 		double atm = depth_to_atm(depth, dive); | ||||
| 
 | ||||
| 		pressuretime += atm * time; | ||||
|  | @ -691,14 +695,14 @@ static int sac_between(struct dive *dive, struct plot_data *first, struct plot_d | |||
| } | ||||
| 
 | ||||
| /* Which of the set of gases have pressure data */ | ||||
| static unsigned int have_pressures(struct plot_data *entry, unsigned int gases) | ||||
| static unsigned int have_pressures(struct plot_info *pi, int idx, unsigned int gases) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i = 0; i < MAX_CYLINDERS; i++) { | ||||
| 		unsigned int mask = 1 << i; | ||||
| 		if (gases & mask) { | ||||
| 			if (!get_plot_pressure(entry, i)) | ||||
| 			if (!get_plot_pressure(pi, idx, i)) | ||||
| 				gases &= ~mask; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -712,7 +716,7 @@ static unsigned int have_pressures(struct plot_data *entry, unsigned int gases) | |||
| static void fill_sac(struct dive *dive, struct plot_info *pi, int idx, unsigned int gases) | ||||
| { | ||||
| 	struct plot_data *entry = pi->entry + idx; | ||||
| 	struct plot_data *first, *last; | ||||
| 	int first, last; | ||||
| 	int time; | ||||
| 
 | ||||
| 	if (entry->sac) | ||||
|  | @ -722,7 +726,7 @@ static void fill_sac(struct dive *dive, struct plot_info *pi, int idx, unsigned | |||
| 	 * We may not have pressure data for all the cylinders, | ||||
| 	 * but we'll calculate the SAC for the ones we do have. | ||||
| 	 */ | ||||
| 	gases = have_pressures(entry, gases); | ||||
| 	gases = have_pressures(pi, idx, gases); | ||||
| 	if (!gases) | ||||
| 		return; | ||||
| 
 | ||||
|  | @ -730,37 +734,39 @@ static void fill_sac(struct dive *dive, struct plot_info *pi, int idx, unsigned | |||
| 	 * Try to go back 30 seconds to get 'first'. | ||||
| 	 * Stop if the cylinder pressure data set changes. | ||||
| 	 */ | ||||
| 	first = entry; | ||||
| 	first = idx; | ||||
| 	time = entry->sec - 30; | ||||
| 	while (idx > 0) { | ||||
| 		struct plot_data *prev = first-1; | ||||
| 		struct plot_data *entry = pi->entry + idx; | ||||
| 		struct plot_data *prev = pi->entry + idx - 1; | ||||
| 
 | ||||
| 		if (prev->depth < SURFACE_THRESHOLD && first->depth < SURFACE_THRESHOLD) | ||||
| 		if (prev->depth < SURFACE_THRESHOLD && entry->depth < SURFACE_THRESHOLD) | ||||
| 			break; | ||||
| 		if (prev->sec < time) | ||||
| 			break; | ||||
| 		if (have_pressures(prev, gases) != gases) | ||||
| 		if (have_pressures(pi, idx - 1, gases) != gases) | ||||
| 			break; | ||||
| 		idx--; | ||||
| 		first = prev; | ||||
| 		first = idx; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Now find an entry a minute after the first one */ | ||||
| 	last = first; | ||||
| 	time = first->sec + 60; | ||||
| 	time = pi->entry[first].sec + 60; | ||||
| 	while (++idx < pi->nr) { | ||||
| 		struct plot_data *next = last+1; | ||||
| 		if (next->depth < SURFACE_THRESHOLD && last->depth < SURFACE_THRESHOLD) | ||||
| 		struct plot_data *entry = pi->entry + last; | ||||
| 		struct plot_data *next = pi->entry + last + 1; | ||||
| 		if (next->depth < SURFACE_THRESHOLD && entry->depth < SURFACE_THRESHOLD) | ||||
| 			break; | ||||
| 		if (next->sec > time) | ||||
| 			break; | ||||
| 		if (have_pressures(next, gases) != gases) | ||||
| 		if (have_pressures(pi, idx + 1, gases) != gases) | ||||
| 			break; | ||||
| 		last = next; | ||||
| 		last = idx; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Ok, now calculate the SAC between 'first' and 'last' */ | ||||
| 	entry->sac = sac_between(dive, first, last, gases); | ||||
| 	entry->sac = sac_between(dive, pi, first, last, gases); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -1401,18 +1407,19 @@ struct divecomputer *select_dc(struct dive *dive) | |||
| 	return get_dive_dc(dive, i); | ||||
| } | ||||
| 
 | ||||
| static void plot_string(struct plot_info *pi, struct plot_data *entry, struct membuffer *b) | ||||
| static void plot_string(struct plot_info *pi, int idx, struct membuffer *b) | ||||
| { | ||||
| 	int pressurevalue, mod, ead, end, eadd; | ||||
| 	const char *depth_unit, *pressure_unit, *temp_unit, *vertical_speed_unit; | ||||
| 	double depthvalue, tempvalue, speedvalue, sacvalue; | ||||
| 	int decimals, cyl; | ||||
| 	const char *unit; | ||||
| 	struct plot_data *entry = pi->entry + idx; | ||||
| 
 | ||||
| 	depthvalue = get_depth_units(entry->depth, NULL, &depth_unit); | ||||
| 	put_format_loc(b, translate("gettextFromC", "@: %d:%02d\nD: %.1f%s\n"), FRACTION(entry->sec, 60), depthvalue, depth_unit); | ||||
| 	for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) { | ||||
| 		int mbar = get_plot_pressure(entry, cyl); | ||||
| 		int mbar = get_plot_pressure(pi, idx, cyl); | ||||
| 		if (!mbar) | ||||
| 			continue; | ||||
| 		struct gasmix mix = displayed_dive.cylinder[cyl].gasmix; | ||||
|  | @ -1553,54 +1560,53 @@ static void plot_string(struct plot_info *pi, struct plot_data *entry, struct me | |||
| 	strip_mb(b); | ||||
| } | ||||
| 
 | ||||
| struct plot_data *get_plot_details_new(struct plot_info *pi, int time, struct membuffer *mb) | ||||
| int get_plot_details_new(struct plot_info *pi, int time, struct membuffer *mb) | ||||
| { | ||||
| 	struct plot_data *entry = NULL; | ||||
| 	int i; | ||||
| 
 | ||||
| 	/* The two first and the two last plot entries do not have useful data */ | ||||
| 	if (pi->nr <= 4) | ||||
| 		return 0; | ||||
| 	for (i = 2; i < pi->nr - 2; i++) { | ||||
| 		entry = pi->entry + i; | ||||
| 		if (entry->sec >= time) | ||||
| 		if (pi->entry[i].sec >= time) | ||||
| 			break; | ||||
| 	} | ||||
| 	if (entry) | ||||
| 		plot_string(pi, entry, mb); | ||||
| 	return entry; | ||||
| 	plot_string(pi, i, mb); | ||||
| 	return i; | ||||
| } | ||||
| 
 | ||||
| /* Compare two plot_data entries and writes the results into a string */ | ||||
| void compare_samples(struct plot_data *e1, struct plot_data *e2, char *buf, int bufsize, int sum) | ||||
| void compare_samples(struct plot_info *pi, int idx1, int idx2, char *buf, int bufsize, bool sum) | ||||
| { | ||||
| 	struct plot_data *start, *stop, *data; | ||||
| 	const char *depth_unit, *pressure_unit, *vertical_speed_unit; | ||||
| 	char *buf2 = malloc(bufsize); | ||||
| 	int avg_speed, max_asc_speed, max_desc_speed; | ||||
| 	int delta_depth, avg_depth, max_depth, min_depth; | ||||
| 	int bar_used, last_pressure, pressurevalue; | ||||
| 	int count, last_sec, delta_time; | ||||
| 	int bar_used, last_pressure, next_pressure, pressurevalue; | ||||
| 	int last_sec, delta_time; | ||||
| 	bool crossed_tankchange = false; | ||||
| 
 | ||||
| 	double depthvalue, speedvalue; | ||||
| 
 | ||||
| 	if (bufsize > 0) | ||||
| 		buf[0] = '\0'; | ||||
| 	if (e1 == NULL || e2 == NULL) { | ||||
| 	if (idx1 < 0 || idx2 < 0) { | ||||
| 		free(buf2); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (e1->sec < e2->sec) { | ||||
| 		start = e1; | ||||
| 		stop = e2; | ||||
| 	} else if (e1->sec > e2->sec) { | ||||
| 		start = e2; | ||||
| 		stop = e1; | ||||
| 	} else { | ||||
| 	if (pi->entry[idx1].sec > pi->entry[idx2].sec) { | ||||
| 		int tmp = idx2; | ||||
| 		idx2 = idx1; | ||||
| 		idx1 = tmp; | ||||
| 	} else if (pi->entry[idx1].sec == pi->entry[idx2].sec) { | ||||
| 		free(buf2); | ||||
| 		return; | ||||
| 	} | ||||
| 	count = 0; | ||||
| 	start = pi->entry + idx1; | ||||
| 	stop = pi->entry + idx2; | ||||
| 
 | ||||
| 	avg_speed = 0; | ||||
| 	max_asc_speed = 0; | ||||
| 	max_desc_speed = 0; | ||||
|  | @ -1613,11 +1619,11 @@ void compare_samples(struct plot_data *e1, struct plot_data *e2, char *buf, int | |||
| 	bar_used = 0; | ||||
| 
 | ||||
| 	last_sec = start->sec; | ||||
| 	last_pressure = get_plot_pressure(start, 0); | ||||
| 	last_pressure = get_plot_pressure(pi, idx1, 0); | ||||
| 
 | ||||
| 	data = start; | ||||
| 	while (data != stop) { | ||||
| 		data = start + count; | ||||
| 	for (int i = idx1; i < idx2; ++i) { | ||||
| 		data = pi->entry + i; | ||||
| 		if (sum) | ||||
| 			avg_speed += abs(data->speed) * (data->sec - last_sec); | ||||
| 		else | ||||
|  | @ -1634,12 +1640,12 @@ void compare_samples(struct plot_data *e1, struct plot_data *e2, char *buf, int | |||
| 		if (data->depth > max_depth) | ||||
| 			max_depth = data->depth; | ||||
| 		/* Try to detect gas changes - this hack might work for some side mount scenarios? */ | ||||
| 		if (get_plot_pressure(data, 0) < last_pressure + 2000) | ||||
| 			bar_used += last_pressure - get_plot_pressure(data, 0); | ||||
| 		next_pressure = get_plot_pressure(pi, i, 0); | ||||
| 		if (next_pressure < last_pressure + 2000) | ||||
| 			bar_used += last_pressure - next_pressure; | ||||
| 
 | ||||
| 		count += 1; | ||||
| 		last_sec = data->sec; | ||||
| 		last_pressure = get_plot_pressure(data, 0); | ||||
| 		last_pressure = next_pressure; | ||||
| 	} | ||||
| 	avg_depth /= stop->sec - start->sec; | ||||
| 	avg_speed /= stop->sec - start->sec; | ||||
|  | @ -1686,15 +1692,15 @@ void compare_samples(struct plot_data *e1, struct plot_data *e2, char *buf, int | |||
| 			double volume_value; | ||||
| 			int volume_precision; | ||||
| 			const char *volume_unit; | ||||
| 			struct plot_data *first = start; | ||||
| 			struct plot_data *last = stop; | ||||
| 			while (first < stop && get_plot_pressure(first, 0) == 0) | ||||
| 			int first = idx1; | ||||
| 			int last = idx2; | ||||
| 			while (first < last && get_plot_pressure(pi, first, 0) == 0) | ||||
| 				first++; | ||||
| 			while (last > first && get_plot_pressure(last, 0) == 0) | ||||
| 			while (last > first && get_plot_pressure(pi, last, 0) == 0) | ||||
| 				last--; | ||||
| 
 | ||||
| 			pressure_t first_pressure = { get_plot_pressure(first, 0) }; | ||||
| 			pressure_t stop_pressure = { get_plot_pressure(last, 0) }; | ||||
| 			pressure_t first_pressure = { get_plot_pressure(pi, first, 0) }; | ||||
| 			pressure_t stop_pressure = { get_plot_pressure(pi, last, 0) }; | ||||
| 			int volume_used = gas_volume(cyl, first_pressure) - gas_volume(cyl, stop_pressure); | ||||
| 
 | ||||
| 			/* Mean pressure in ATM */ | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| #define PROFILE_H | ||||
| 
 | ||||
| #include "dive.h" | ||||
| #include "display.h" | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
|  | @ -78,12 +79,12 @@ struct ev_select { | |||
| 	bool plot_ev; | ||||
| }; | ||||
| 
 | ||||
| extern void compare_samples(struct plot_data *e1, struct plot_data *e2, char *buf, int bufsize, int sum); | ||||
| extern void compare_samples(struct plot_info *p1, int idx1, int idx2, char *buf, int bufsize, bool sum); | ||||
| extern struct plot_info *analyze_plot_info(struct plot_info *pi); | ||||
| extern void init_plot_info(struct plot_info *pi); | ||||
| extern void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plot_info *pi, bool fast, struct deco_state *planner_ds); | ||||
| extern void calculate_deco_information(struct deco_state *ds, const struct deco_state *planner_de, const struct dive *dive, const struct divecomputer *dc, struct plot_info *pi, bool print_mode); | ||||
| extern struct plot_data *get_plot_details_new(struct plot_info *pi, int time, struct membuffer *); | ||||
| extern int get_plot_details_new(struct plot_info *pi, int time, struct membuffer *); | ||||
| extern void free_plot_info_data(struct plot_info *pi); | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -121,10 +122,11 @@ static inline int get_plot_interpolated_pressure(const struct plot_data *entry, | |||
| 	return get_plot_pressure_data(entry, INTERPOLATED_PR, idx); | ||||
| } | ||||
| 
 | ||||
| static inline int get_plot_pressure(const struct plot_data *entry, int idx) | ||||
| static inline int get_plot_pressure(const struct plot_info *pi, int idx, int cylinder) | ||||
| { | ||||
| 	int res = get_plot_sensor_pressure(entry, idx); | ||||
| 	return res ? res : get_plot_interpolated_pressure(entry, idx); | ||||
| 	const struct plot_data *entry = pi->entry + idx; | ||||
| 	int res = get_plot_sensor_pressure(entry, cylinder); | ||||
| 	return res ? res : get_plot_interpolated_pressure(entry, cylinder); | ||||
| } | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
|  |  | |||
|  | @ -665,11 +665,12 @@ void DiveGasPressureItem::modelDataChanged(const QModelIndex &topLeft, const QMo | |||
| 	QPolygonF boundingPoly; | ||||
| 	polygons.clear(); | ||||
| 
 | ||||
| 	const struct plot_info *pInfo = &dataModel->data(); | ||||
| 	for (int i = 0, count = dataModel->rowCount(); i < count; i++) { | ||||
| 		struct plot_data *entry = dataModel->data().entry + i; | ||||
| 		const struct plot_data *entry = pInfo->entry + i; | ||||
| 
 | ||||
| 		for (int cyl = 0; cyl < MAX_CYLINDERS; cyl++) { | ||||
| 			int mbar = get_plot_pressure(entry, cyl); | ||||
| 			int mbar = get_plot_pressure(pInfo, i, cyl); | ||||
| 			int time = entry->sec; | ||||
| 
 | ||||
| 			if (!mbar) | ||||
|  | @ -726,10 +727,10 @@ void DiveGasPressureItem::modelDataChanged(const QModelIndex &topLeft, const QMo | |||
| 	double axisLog = log10(log10(axisRange)); | ||||
| 
 | ||||
| 	for (int i = 0, count = dataModel->rowCount(); i < count; i++) { | ||||
| 		struct plot_data *entry = dataModel->data().entry + i; | ||||
| 		const struct plot_data *entry = pInfo->entry + i; | ||||
| 
 | ||||
| 		for (int cyl = 0; cyl < MAX_CYLINDERS; cyl++) { | ||||
| 			int mbar = get_plot_pressure(entry, cyl); | ||||
| 			int mbar = get_plot_pressure(pInfo, i, cyl); | ||||
| 
 | ||||
| 			if (!mbar) | ||||
| 				continue; | ||||
|  |  | |||
|  | @ -230,7 +230,6 @@ void ToolTipItem::setTimeAxis(DiveCartesianAxis *axis) | |||
| 
 | ||||
| void ToolTipItem::refresh(const QPointF &pos) | ||||
| { | ||||
| 	struct plot_data *entry; | ||||
| 	static QPixmap tissues(16,60); | ||||
| 	static QPainter painter(&tissues); | ||||
| 	static struct membuffer mb = {}; | ||||
|  | @ -245,7 +244,7 @@ void ToolTipItem::refresh(const QPointF &pos) | |||
| 	clear(); | ||||
| 
 | ||||
| 	mb.len = 0; | ||||
| 	entry = get_plot_details_new(&pInfo, time, &mb); | ||||
| 	int idx = get_plot_details_new(&pInfo, time, &mb); | ||||
| 
 | ||||
| 	tissues.fill(); | ||||
| 	painter.setPen(QColor(0, 0, 0, 0)); | ||||
|  | @ -255,10 +254,11 @@ void ToolTipItem::refresh(const QPointF &pos) | |||
| 	painter.drawRect(0, 10, 16, (100 - AMB_PERCENTAGE) / 2); | ||||
| 	painter.setBrush(QColor(Qt::red)); | ||||
| 	painter.drawRect(0,0,16,10); | ||||
| 	if (entry) { | ||||
| 	if (idx) { | ||||
| 		ProfileWidget2 *view = qobject_cast<ProfileWidget2*>(scene()->views().first()); | ||||
| 		Q_ASSERT(view); | ||||
| 
 | ||||
| 		const struct plot_data *entry = &pInfo.entry[idx]; | ||||
| 		painter.setPen(QColor(0, 0, 0, 255)); | ||||
| 		if (decoMode() == BUEHLMANN) | ||||
| 			painter.drawLine(0, lrint(60 - entry->gfline / 2), 16, lrint(60 - entry->gfline / 2)); | ||||
|  |  | |||
|  | @ -116,7 +116,7 @@ void RulerItem2::recalculate() | |||
| 	} | ||||
| 	QLineF line(startPoint, endPoint); | ||||
| 	setLine(line); | ||||
| 	compare_samples(&pInfo.entry[source->idx], &pInfo.entry[dest->idx], buffer, 500, 1); | ||||
| 	compare_samples(&pInfo, source->idx, dest->idx, buffer, 500, 1); | ||||
| 	text = QString(buffer); | ||||
| 
 | ||||
| 	// draw text
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue