diff --git a/js/model.ts b/js/model.ts index 49566e3..8a8add9 100644 --- a/js/model.ts +++ b/js/model.ts @@ -1,7 +1,7 @@ export enum DayType { NoData = 0, None, Shower, Rainbow, Aurora } export enum ShowerType { NotSure = 0, Light, Heavy } -import {Hemisphere, Weather, SpecialDay, getMonthLength, Pattern, getPattern, getWeather, getWindPower, isSpecialDay, SnowLevel, CloudLevel, FogLevel, getSnowLevel, getCloudLevel, getFogLevel, checkWaterFog, getRainbowInfo, isAuroraPattern, fromLinearHour, toLinearHour, canHaveShootingStars, queryStars, getStarSecond, isLightShowerPattern, isHeavyShowerPattern, isPatternPossibleAtDate, GuessData, getPatternKind, PatternKind, SpWeatherLevel, getSpWeatherLevel, Constellation, getConstellation, getWindPowerMin, getWindPowerMax, getSpecialCloudInfo, SpecialCloud} from '../pkg' +import {Hemisphere, Weather, SpecialDay, getMonthLength, Pattern, getPattern, getWeather, getWindPower, isSpecialDay, SnowLevel, CloudLevel, FogLevel, getSnowLevel, getCloudLevel, getFogLevel, checkWaterFog, getRainbowInfo, isAuroraPattern, fromLinearHour, toLinearHour, canHaveShootingStars, isLightShowerPattern, isHeavyShowerPattern, isPatternPossibleAtDate, GuessData, getPatternKind, PatternKind, SpWeatherLevel, getSpWeatherLevel, Constellation, getConstellation, getWindPowerMin, getWindPowerMax, getSpecialCloudInfo, SpecialCloud, StarsIterator} from '../pkg' export {Hemisphere, Weather, SpecialDay, getMonthLength} export enum AmbiguousWeather { @@ -628,12 +628,16 @@ export class DayForecast { const hour = fromLinearHour(linearHour) if (canHaveShootingStars(hour, this.pattern)) { for (let minute = 0; minute < 60; minute++) { - const starCount = queryStars(seed, year, month, day, hour, minute, this.pattern) - if (starCount > 0) { - const star: StarInfo = {hour, minute, seconds: []} - for (let i = 0; i < starCount; i++) { - star.seconds.push(getStarSecond(i)) - } + const starsIterator = new StarsIterator(seed, year, month, day, hour, minute, this.pattern); + const star: StarInfo = {hour, minute, seconds: []} + + while (starsIterator.hasNext()) { + const second = starsIterator.next()!; + + star.seconds.push(second); + } + + if (star.seconds.length > 0) { this.shootingStars.push(star) } } diff --git a/src/lib.rs b/src/lib.rs index a8b0796..b8acbbf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -641,34 +641,55 @@ fn query_stars_internal(seed_base: u32, minute: u8, pattern: Pattern) -> Option< } +#[wasm_bindgen] +pub struct StarsIterator { + star_count: u8, + star_field: u64, + second: u8, +} + +#[wasm_bindgen] +impl StarsIterator { + #[wasm_bindgen(constructor)] + pub fn new(seed: u32, year: u16, month: u8, day: u8, hour: u8, minute: u8, pattern: Pattern) -> Self { + let (year, month, day) = normalise_late_ymd(year, month, day, hour); + let seed = compute_seed_ymdh(seed, 0x20000, 0x2000, 0x100, 0x10000, year, month, day, hour); + + let (star_count, star_field) = query_stars_internal(seed, minute, pattern) + .unwrap_or((0, 0)); + + Self { + star_count, + star_field, + second: 0, + } + } -static mut LAST_STAR_SECONDS: [u8;8] = [0;8]; + #[wasm_bindgen(js_name = hasNext)] + pub fn has_next(&self) -> bool { + self.star_count > 0 + } -#[wasm_bindgen(js_name = queryStars)] -pub fn query_stars(seed: u32, year: u16, month: u8, day: u8, hour: u8, minute: u8, pattern: Pattern) -> u8 { - let (year, month, day) = normalise_late_ymd(year, month, day, hour); - let seed = compute_seed_ymdh(seed, 0x20000, 0x2000, 0x100, 0x10000, year, month, day, hour); - match query_stars_internal(seed, minute, pattern) { - None => 0, - Some((star_count, star_field)) => { - let mut index = 0; - for second in 0..60 { - let mask = 1u64 << second; - if (star_field & mask) != 0 { - unsafe { LAST_STAR_SECONDS[index] = second; } - index += 1; - } + #[allow(clippy::should_implement_trait)] + pub fn next(&mut self) -> Option { + if !self.has_next() { + return None; + } + + for second in self.second..60 { + let mask = 1u64 << second; + + if (self.star_field & mask) != 0 { + self.second = second + 1; + self.star_count -= 1; + + return Some(second); } - star_count } + + None } } -#[wasm_bindgen(js_name = getStarSecond)] -pub fn get_star_second(index: usize) -> u8 { - unsafe { LAST_STAR_SECONDS[index] } -} - - #[derive(Clone, Copy)]