Skip to content

Commit

Permalink
fix(rmp): RateScheduler unscheduling not working (flybywiresim#3358)
Browse files Browse the repository at this point in the history
* bugfix

* lint

* jsdoc
  • Loading branch information
Theodore Messinezis authored Feb 6, 2021
1 parent 359af5b commit cb2f637
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 21 deletions.
43 changes: 25 additions & 18 deletions src/instruments/src/RMP/Framework/RateScheduler.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,50 @@
*/
export class RateScheduler {
constructor() {
this.map = new Map();
this.rates = new Map();
this.callbacks = new Map();
}

/**
* Schedule a new callback to be called at a set rate.
* @param identifier The identifier for the callback
* @param callback The callback to be scheduled
* @param rate The rate that this callback should be called at.
*/
schedule(callback, rate) {
if (this.map.has(rate)) {
this.map.get(rate).callbacks.push(callback);
schedule(identifier, callback, rate) {
this.callbacks.set(identifier, callback);

if (this.rates.has(rate)) {
this.rates.get(rate).identifiers.push(identifier);
return;
}

this.map.set(rate, {
this.rates.set(rate, {
interval: setInterval(() => this.tick(rate), rate),
callbacks: [callback],
identifiers: [identifier],
});
}

/**
* Remove a given callback (from all rates).
* @param callback The callback to unschedule.
* Remove a given identifier (from all rates).
* @param identifier The identifier to unschedule.
*/
unschedule(callback) {
this.map.forEach((value) => {
value.callbacks = value.callbacks.filter((cb) => cb !== callback);
unschedule(identifier) {
this.callbacks.delete(identifier);

this.rates.forEach((value) => {
value.identifiers = value.identifiers.filter((ident) => ident !== identifier);
});

this.cleanup();
}

/**
* Clears intervals that have no callbacks.
* Clears intervals that have no intervals.
*/
cleanup() {
this.map.forEach((value, key, map) => {
if (value.callbacks.length === 0) {
this.rates.forEach((value, key, map) => {
if (value.identifiers.length === 0) {
clearInterval(value.interval);
map.delete(key);
}
Expand All @@ -53,10 +59,11 @@ export class RateScheduler {
* @param rate The rate of the interval that called.
*/
tick(rate) {
if (!this.map.has(rate)) {
return;
}
if (!this.rates.has(rate)) return;

this.map.get(rate).callbacks.forEach((cb) => cb());
this.rates.get(rate).identifiers.forEach((identifier) => {
const callback = this.callbacks.get(identifier);
if (typeof callback === 'function') callback();
});
}
}
5 changes: 2 additions & 3 deletions src/instruments/src/RMP/Framework/StatefulSimVar.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export class StatefulSimVar extends CachedSimVar {
constructor(options) {
super(options);

this.refreshCallback = () => this.refresh();
this.rateScheduler = options.rateScheduler || globalRateScheduler;

const [state, setState] = useState(super.value);
Expand Down Expand Up @@ -46,7 +45,7 @@ export class StatefulSimVar extends CachedSimVar {
* @param refreshRate The refresh delay in ms. False-y to stop refreshing.
*/
setRefreshRate(refreshRate) {
this.rateScheduler.unschedule(this.refreshCallback);
if (refreshRate) this.rateScheduler.schedule(this.refreshCallback, refreshRate);
this.rateScheduler.unschedule(this.identifier);
if (refreshRate) this.rateScheduler.schedule(this.identifier, this.refresh.bind(this), refreshRate);
}
}

0 comments on commit cb2f637

Please sign in to comment.