mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	Refactoring: Improve event_loop.
				
					
				
			Improve the event loop architecture by making it set the divecomputer in the constructor - using the same loop for multiple dive computers is not intended to work. Also change `next()` in `divemode_loop` to `at()` to make the name more aligned with its function. Signed-off-by: Michael Keller <github@ike.ch>
This commit is contained in:
		
							parent
							
								
									33bb39f1ca
								
							
						
					
					
						commit
						ee25e8a1db
					
				
					 11 changed files with 28 additions and 33 deletions
				
			
		|  | @ -2554,7 +2554,7 @@ location_t dive::get_gps_location() const | |||
| } | ||||
| 
 | ||||
| gasmix_loop::gasmix_loop(const struct dive &d, const struct divecomputer &dc) : | ||||
| 	dive(d), dc(dc), first_run(true), loop("gaschange") | ||||
| 	dive(d), dc(dc), first_run(true), loop("gaschange", dc) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  | @ -2571,13 +2571,13 @@ std::pair<int, int> gasmix_loop::next_cylinder_index() | |||
| 		return std::make_pair(-1, INT_MAX); | ||||
| 
 | ||||
| 	if (first_run) { | ||||
| 		next_event = loop.next(dc); | ||||
| 		next_event = loop.next(); | ||||
| 		last_cylinder_index = 0; // default to first cylinder
 | ||||
| 		last_time = 0; | ||||
| 		if (next_event && ((!dc.samples.empty() && next_event->time.seconds == dc.samples[0].time.seconds) || next_event->time.seconds <= 1)) { | ||||
| 			last_cylinder_index = dive.get_cylinder_index(*next_event); | ||||
| 			last_time = next_event->time.seconds; | ||||
| 			next_event = loop.next(dc); | ||||
| 			next_event = loop.next(); | ||||
| 		} else if (dc.divemode == CCR) { | ||||
| 			last_cylinder_index = std::max(get_cylinder_idx_by_use(dive, DILUENT), last_cylinder_index); | ||||
| 		} | ||||
|  | @ -2587,7 +2587,7 @@ std::pair<int, int> gasmix_loop::next_cylinder_index() | |||
| 		if (next_event) { | ||||
| 			last_cylinder_index = dive.get_cylinder_index(*next_event); | ||||
| 			last_time = next_event->time.seconds; | ||||
| 			next_event = loop.next(dc); | ||||
| 			next_event = loop.next(); | ||||
| 		} else { | ||||
| 			last_cylinder_index = -1; | ||||
| 			last_time = INT_MAX; | ||||
|  |  | |||
|  | @ -200,17 +200,17 @@ void fake_dc(struct divecomputer *dc) | |||
| } | ||||
| 
 | ||||
| divemode_loop::divemode_loop(const struct divecomputer &dc) : | ||||
| 	dc(dc), last(dc.divemode), loop("modechange") | ||||
| 	last(dc.divemode), loop("modechange", dc) | ||||
| { | ||||
| 	/* on first invocation, get first event (if any) */ | ||||
| 	ev = loop.next(dc); | ||||
| 	ev = loop.next(); | ||||
| } | ||||
| 
 | ||||
| divemode_t divemode_loop::next(int time) | ||||
| divemode_t divemode_loop::at(int time) | ||||
| { | ||||
| 	while (ev && ev->time.seconds <= time) { | ||||
| 		last = static_cast<divemode_t>(ev->value); | ||||
| 		ev = loop.next(dc); | ||||
| 		ev = loop.next(); | ||||
| 	} | ||||
| 	return last; | ||||
| } | ||||
|  |  | |||
|  | @ -433,7 +433,7 @@ static void add_dive_to_deco(struct deco_state *ds, const struct dive &dive, boo | |||
| 			int depth = interpolate(psample.depth.mm, sample.depth.mm, j - t0, t1 - t0); | ||||
| 			auto gasmix = loop.at(j).first; | ||||
| 			add_segment(ds, dive.depth_to_bar(depth), gasmix, 1, sample.setpoint.mbar, | ||||
| 				    loop_d.next(j), dive.sac, | ||||
| 				    loop_d.at(j), dive.sac, | ||||
| 				    in_planner); | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -81,27 +81,22 @@ enum event_severity event::get_severity() const | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| event_loop::event_loop(const char *name) : name(name), idx(0) | ||||
| event_loop::event_loop(const char *name, const struct divecomputer &dc) : name(name), idx(0), dc(dc) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| struct event *event_loop::next(struct divecomputer &dc) | ||||
| const struct event *event_loop::next() | ||||
| { | ||||
| 	if (name.empty()) | ||||
| 		return nullptr; | ||||
| 	while (idx < dc.events.size()) { | ||||
| 		struct event &ev = dc.events[idx++]; | ||||
| 		const struct event &ev = dc.events[idx++]; | ||||
| 		if (ev.name == name) | ||||
| 			return &ev; | ||||
| 	} | ||||
| 	return nullptr; | ||||
| } | ||||
| 
 | ||||
| const struct event *event_loop::next(const struct divecomputer &dc) | ||||
| { | ||||
| 	return next(const_cast<divecomputer &>(dc)); | ||||
| } | ||||
| 
 | ||||
| struct event *get_first_event(struct divecomputer &dc, const std::string &name) | ||||
| { | ||||
| 	auto it = std::find_if(dc.events.begin(), dc.events.end(), [name](auto &ev) { return ev.name == name; }); | ||||
|  |  | |||
							
								
								
									
										10
									
								
								core/event.h
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								core/event.h
									
										
									
									
									
								
							|  | @ -58,10 +58,10 @@ class event_loop | |||
| { | ||||
| 	std::string name; | ||||
| 	size_t idx; | ||||
| 	const struct divecomputer &dc; | ||||
| public: | ||||
| 	event_loop(const char *name); | ||||
| 	struct event *next(struct divecomputer &dc); // nullptr -> end
 | ||||
| 	const struct event *next(const struct divecomputer &dc); // nullptr -> end
 | ||||
| 	event_loop(const char *name, const struct divecomputer &dc); | ||||
| 	const struct event *next(); // nullptr -> end
 | ||||
| }; | ||||
| 
 | ||||
| /* Get gasmixes at increasing timestamps. */ | ||||
|  | @ -92,13 +92,13 @@ public: | |||
| 
 | ||||
| /* Get divemodes at increasing timestamps. */ | ||||
| class divemode_loop { | ||||
| 	const struct divecomputer &dc; | ||||
| 	divemode_t last; | ||||
| 	event_loop loop; | ||||
| 	const struct event *ev; | ||||
| public: | ||||
| 	divemode_loop(const struct divecomputer &dc); | ||||
| 	divemode_t next(int time); | ||||
| 	// Return the divemode at a given time during the dive
 | ||||
| 	divemode_t at(int time); | ||||
| }; | ||||
| 
 | ||||
| extern const struct event *get_first_event(const struct divecomputer &dc, const std::string &name); | ||||
|  |  | |||
|  | @ -364,7 +364,7 @@ void populate_pressure_information(const struct dive *dive, const struct divecom | |||
| 				cyl = sensor; | ||||
| 		} | ||||
| 
 | ||||
| 		divemode_t dmode = loop_mode.next(time); | ||||
| 		divemode_t dmode = loop_mode.at(time); | ||||
| 
 | ||||
| 		if (current != std::string::npos) { // calculate pressure-time, taking into account the dive mode for this specific segment.
 | ||||
| 			entry.pressure_time = (int)(calc_pressure_time(dive, pi.entry[i - 1], entry) * gasfactor[dmode] + 0.5); | ||||
|  |  | |||
|  | @ -162,7 +162,7 @@ static int tissue_at_end(struct deco_state *ds, struct dive *dive, const struct | |||
| 				ds->max_bottom_ceiling_pressure.mbar = ceiling_pressure.mbar; | ||||
| 		} | ||||
| 
 | ||||
| 		divemode_t divemode = loop.next(t0.seconds + 1); | ||||
| 		divemode_t divemode = loop.at(t0.seconds + 1); | ||||
| 		interpolate_transition(ds, dive, t0, t1, lastdepth, sample.depth, gas, setpoint, divemode); | ||||
| 		psample = &sample; | ||||
| 		t0 = t1; | ||||
|  | @ -720,7 +720,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i | |||
| 	current_cylinder = get_cylinderid_at_time(dive, dc, sample.time); | ||||
| 	// Find the divemode at the end of the dive
 | ||||
| 	divemode_loop loop(*dc); | ||||
| 	divemode = loop.next(bottom_time); | ||||
| 	divemode = loop.at(bottom_time); | ||||
| 	gas = dive->get_cylinder(current_cylinder)->gasmix; | ||||
| 
 | ||||
| 	po2 = sample.setpoint.mbar; | ||||
|  |  | |||
|  | @ -595,7 +595,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d | |||
| 					std::string temp; | ||||
| 					struct gasmix gasmix = dive->get_cylinder(dp->cylinderid)->gasmix; | ||||
| 
 | ||||
| 					divemode_t current_divemode = loop.next(dp->time); | ||||
| 					divemode_t current_divemode = loop.at(dp->time); | ||||
| 					amb = dive->depth_to_atm(dp->depth.mm); | ||||
| 					gas_pressures pressures = fill_pressures(amb, gasmix, (current_divemode == OC) ? 0.0 : amb * gasmix.o2.permille / 1000.0, current_divemode); | ||||
| 
 | ||||
|  |  | |||
|  | @ -212,9 +212,9 @@ static void check_setpoint_events(const struct dive *, const struct divecomputer | |||
| 	pressure_t setpoint; | ||||
| 	setpoint.mbar = 0; | ||||
| 
 | ||||
| 	event_loop loop("SP change"); | ||||
| 	event_loop loop("SP change", *dc); | ||||
| 	bool found = false; | ||||
| 	while (auto ev = loop.next(*dc)) { | ||||
| 	while (auto ev = loop.next()) { | ||||
| 		i = set_setpoint(pi, i, setpoint.mbar, ev->time.seconds); | ||||
| 		setpoint.mbar = ev->value; | ||||
| 		found = true; | ||||
|  | @ -876,7 +876,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_ | |||
| 			int j, t0 = prev.sec, t1 = entry.sec; | ||||
| 			int time_stepsize = 20, max_ceiling = -1; | ||||
| 
 | ||||
| 			divemode_t current_divemode = loop_d.next(entry.sec); | ||||
| 			divemode_t current_divemode = loop_d.at(entry.sec); | ||||
| 			struct gasmix gasmix = loop.at(t1).first; | ||||
| 			entry.ambpressure = dive->depth_to_bar(entry.depth); | ||||
| 			entry.gfline = get_gf(ds, entry.ambpressure, dive) * (100.0 - AMB_PERCENTAGE) + AMB_PERCENTAGE; | ||||
|  | @ -1114,7 +1114,7 @@ static void calculate_gas_information_new(const struct dive *dive, const struct | |||
| 
 | ||||
| 		auto gasmix = loop.at(entry.sec).first; | ||||
| 		amb_pressure = dive->depth_to_bar(entry.depth); | ||||
| 		divemode_t current_divemode = loop_d.next(entry.sec); | ||||
| 		divemode_t current_divemode = loop_d.at(entry.sec); | ||||
| 		entry.pressures = fill_pressures(amb_pressure, gasmix, (current_divemode == OC) ? 0.0 : entry.o2pressure.mbar / 1000.0, current_divemode); | ||||
| 		fn2 = 1000.0 * entry.pressures.n2 / amb_pressure; | ||||
| 		fhe = 1000.0 * entry.pressures.he / amb_pressure; | ||||
|  |  | |||
|  | @ -568,7 +568,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event) | |||
| 	m.addAction(tr("Split dive into two"), [this, seconds]() { splitDive(seconds); }); | ||||
| 
 | ||||
| 	divemode_loop loop(*d->get_dc(dc)); | ||||
| 	divemode_t divemode = loop.next(seconds); | ||||
| 	divemode_t divemode = loop.at(seconds); | ||||
| 	QMenu *changeMode = m.addMenu(tr("Change divemode")); | ||||
| 	if (divemode != OC) | ||||
| 		changeMode->addAction(gettextFromC::tr(divemode_text_ui[OC]), | ||||
|  |  | |||
|  | @ -172,7 +172,7 @@ void DivePlannerPointsModel::loadFromDive(dive *dIn, int dcNrIn) | |||
| 			if (newtime.seconds - lastrecordedtime.seconds > 10 || cylinderid == get_cylinderid_at_time(d, dc, nexttime)) { | ||||
| 				if (newtime.seconds == lastrecordedtime.seconds) | ||||
| 					newtime.seconds += 10; | ||||
| 				divemode_t current_divemode = loop.next(newtime.seconds - 1); | ||||
| 				divemode_t current_divemode = loop.at(newtime.seconds - 1); | ||||
| 				addStop(depthsum / samplecount, newtime.seconds, cylinderid, last_sp.mbar, true, current_divemode); | ||||
| 				lastrecordedtime = newtime; | ||||
| 			} | ||||
|  | @ -182,7 +182,7 @@ void DivePlannerPointsModel::loadFromDive(dive *dIn, int dcNrIn) | |||
| 		} | ||||
| 	} | ||||
| 	// make sure we get the last point right so the duration is correct
 | ||||
| 	divemode_t current_divemode = loop.next(dc->duration.seconds); | ||||
| 	divemode_t current_divemode = loop.at(dc->duration.seconds); | ||||
| 	if (!hasMarkedSamples && !dc->last_manual_time.seconds) | ||||
| 		addStop(0, dc->duration.seconds,cylinderid, last_sp.mbar, true, current_divemode); | ||||
| 	preserved_until = d->duration; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue