Kstars

schedulerjob.h
1/* Ekos Scheduler Job
2 SPDX-FileCopyrightText: Jasem Mutlaq <mutlaqja@ikarustech.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#pragma once
8
9#include "skypoint.h"
10#include "schedulertypes.h"
11#include "ekos/capture/sequencejob.h"
12
13#include <QUrl>
14#include <QMap>
15#include "kstarsdatetime.h"
16#include <QJsonObject>
17
19class KSMoon;
20class TestSchedulerUnit;
21class TestEkosSchedulerOps;
22class dms;
23
24namespace Ekos
25{
26class SchedulerJob
27{
28 public:
29 SchedulerJob();
30
31 QJsonObject toJson() const;
32
33 /** @brief Actions that may be processed when running a SchedulerJob.
34 * FIXME: StepPipeLine is actually a mask, change this into a bitfield.
35 */
36 typedef enum
37 {
38 USE_NONE = 0,
39 USE_TRACK = 1 << 0,
40 USE_FOCUS = 1 << 1,
41 USE_ALIGN = 1 << 2,
42 USE_GUIDE = 1 << 3
43 } StepPipeline;
44
45 struct JobProgress
46 {
47 int numCompleted = 0;
48 CCDFrameType type;
49 bool isDarkFlat = false;
51 JobProgress() {}
52 JobProgress(int numCompleted, const SequenceJob *job)
53 : numCompleted(numCompleted), type(job->getFrameType()),
54 isDarkFlat(job->jobType() == SequenceJob::JOBTYPE_DARKFLAT),
55 properties(job->getCoreProperties()) {};
56 };
57
58 /** @brief Coordinates of the target of this job. */
59 /** @{ */
60 SkyPoint const &getTargetCoords() const
61 {
62 if (m_LeadJob != nullptr)
63 return m_LeadJob->getTargetCoords();
64 else
65 return targetCoords;
66 }
67 void setTargetCoords(const dms &ra, const dms &dec, double djd);
68 /** @} */
69
70 double getPositionAngle()
71 {
72 return m_PositionAngle;
73 }
74 void setPositionAngle(double value);
75
76 /** @brief Capture sequence this job uses while running. */
77 /** @{ */
78 QUrl getSequenceFile() const
79 {
80 return sequenceFile;
81 }
82 void setSequenceFile(const QUrl &value);
83 /** @} */
84
85 /** @brief FITS file whose plate solve produces target coordinates. */
86 /** @{ */
87 QUrl getFITSFile() const
88 {
89 if (m_LeadJob != nullptr)
90 return m_LeadJob->getFITSFile();
91 else
92 return fitsFile;
93 }
94 void setFITSFile(const QUrl &value);
95 /** @} */
96
97 /** @brief Minimal target altitude to process this job */
98 /** @{ */
99 double getMinAltitude() const
100 {
101 if (m_LeadJob != nullptr)
102 return m_LeadJob->getMinAltitude();
103 else
104 return minAltitude;
105 }
106 void setMinAltitude(const double &value);
107 /** @} */
108
109 /** @brief Does this job have a min-altitude parameter. */
110 /** @{ */
111 bool hasMinAltitude() const
112 {
113 return UNDEFINED_ALTITUDE < getMinAltitude();
114 }
115 static constexpr int UNDEFINED_ALTITUDE = -90;
116 /** @} */
117
118 /** @brief Does this job have any altitude constraints. */
119 /** @{ */
120 bool hasAltitudeConstraint() const;
121 /** @} */
122
123 /** @brief Minimal Moon separation to process this job. */
124 /** @{ */
125 double getMinMoonSeparation() const
126 {
127 if (m_LeadJob != nullptr)
128 return m_LeadJob->getMinMoonSeparation();
129 else
130 return minMoonSeparation;
131 }
132 void setMinMoonSeparation(const double &value);
133 /** @} */
134
135 /** @brief Whether to restrict this job to good weather. */
136 /** @{ */
137 bool getEnforceWeather() const
138 {
139 if (m_LeadJob != nullptr)
140 return m_LeadJob->getEnforceWeather();
141 else
142 return enforceWeather;
143 }
144 void setEnforceWeather(bool value);
145 /** @} */
146
147 /** @brief Mask of actions to process for this job. */
148 /** @{ */
149 StepPipeline getStepPipeline() const
150 {
151 if (m_LeadJob != nullptr)
152 return m_LeadJob->getStepPipeline();
153 else
154 return stepPipeline;
155 }
156 void setStepPipeline(const StepPipeline &value);
157 /** @} */
158
159 /** @brief Condition under which this job starts. */
160 /** @{ */
161 StartupCondition getStartupCondition() const
162 {
163 if (m_LeadJob != nullptr)
164 return m_LeadJob->getStartupCondition();
165 else
166 return startupCondition;
167 }
168 void setStartupCondition(const StartupCondition &value);
169 /** @} */
170
171 /** @brief Condition under which this job completes. */
172 /** @{ */
173 CompletionCondition getCompletionCondition() const
174 {
175 return completionCondition;
176 }
177 void setCompletionCondition(const CompletionCondition &value);
178 /** @} */
179
180 /** @brief Original startup condition, as entered by the user. */
181 /** @{ */
182 StartupCondition getFileStartupCondition() const
183 {
184 if (m_LeadJob != nullptr)
185 return m_LeadJob->getFileStartupCondition();
186 else
187 return fileStartupCondition;
188 }
189 void setFileStartupCondition(const StartupCondition &value);
190 /** @} */
191
192 /** @brief Original time at which the job must start, as entered by the user. */
193 /** @{ */
194 QDateTime getStartAtTime() const
195 {
196 if (m_LeadJob != nullptr)
197 return m_LeadJob->getStartAtTime();
198 else
199 return startAtTime;
200 }
201 void setStartAtTime(const QDateTime &value);
202 /** @} */
203
204 /** @brief Whether this job requires re-focus while running its capture sequence. */
205 /** @{ */
206 bool getInSequenceFocus() const
207 {
208 return inSequenceFocus;
209 }
210 void setInSequenceFocus(bool value);
211 /** @} */
212
213 /** @brief Whether to restrict job to night time. */
214 /** @{ */
215 bool getEnforceTwilight() const
216 {
217 if (m_LeadJob != nullptr)
218 return m_LeadJob->getEnforceTwilight();
219 else
220 return enforceTwilight;
221 }
222 void setEnforceTwilight(bool value);
223 /** @} */
224
225 /** @brief Whether to restrict job to night time. */
226 /** @{ */
227 bool getEnforceArtificialHorizon() const
228 {
229 if (m_LeadJob != nullptr)
230 return m_LeadJob->getEnforceArtificialHorizon();
231 else
232 return enforceArtificialHorizon;
233 }
234 void setEnforceArtificialHorizon(bool value);
235 /** @} */
236
237 /** @brief Current name of the scheduler job. */
238 /** @{ */
239 QString getName() const
240 {
241 if (m_LeadJob != nullptr)
242 return m_LeadJob->getName();
243 else
244 return name;
245 }
246 void setName(const QString &value);
247 /** @} */
248
249 /** @brief Flag if the scheduler job is a lead job with its own target or if it is a follower job to another lead job. */
250 /** @{ */
251 bool isLead() const
252 {
253 return m_isLead;
254 }
255 void setIsLead(bool value)
256 {
257 m_isLead = value;
258 }
259 /** @} */
260
261 /** @brief Group the scheduler job belongs to. */
262 /** @{ */
263 QString getGroup() const
264 {
265 if (m_LeadJob != nullptr)
266 return m_LeadJob->getGroup();
267 else
268 return group;
269 }
270 void setGroup(const QString &value);
271 /** @} */
272
273 /** @brief Optical train the scheduler job will be using. */
274 /** @{ */
275 QString getOpticalTrain() const
276 {
277 return opticalTrain;
278 }
279 void setOpticalTrain(const QString &value)
280 {
281 opticalTrain = value;
282 }
283 /** @} */
284
285 /** @brief Iteration the scheduler job has achieved. This only makes sense for jobs that repeat. */
286 /** @{ */
287 int getCompletedIterations() const
288 {
289 return completedIterations;
290 }
291 void setCompletedIterations(int value);
292 /** @} */
293
294 /** @brief Current state of the scheduler job.
295 * Setting state to JOB_ABORTED automatically resets the startup characteristics.
296 * Setting state to JOB_INVALID automatically resets the startup characteristics and the duration estimation.
297 * @see SchedulerJob::setStartupCondition, SchedulerJob::setFileStartupCondition, SchedulerJob::setStartupTime
298 * and SchedulerJob::setFileStartupTime.
299 */
300 /** @{ */
301 SchedulerJobStatus getState() const
302 {
303 return state;
304 }
305
306 /**
307 * @brief isStopped helper function for idle or aborted state
308 */
309 bool isStopped() const
310 {
311 return (state == SCHEDJOB_IDLE || state == SCHEDJOB_ABORTED);
312 }
313 QDateTime getStateTime() const
314 {
315 return stateTime;
316 }
317 QDateTime getLastAbortTime() const
318 {
319 return lastAbortTime;
320 }
321 QDateTime getLastErrorTime() const
322 {
323 return lastErrorTime;
324 }
325 void setState(const SchedulerJobStatus &value, bool force = false);
326
327 void setFollowerState(const SchedulerJobStatus &value, bool force);
328
329 /**
330 * @brief Update the attributes of all followers that are shared with the lead job
331 */
332 void updateSharedFollowerAttributes();
333 /** @} */
334
335 /** @brief Current stage of the scheduler job. */
336 /** @{ */
337 SchedulerJobStage getStage() const
338 {
339 return stage;
340 }
341 void setStage(const SchedulerJobStage &value);
342 /** @} */
343
344 /** @brief Number of captures required in the associated sequence. */
345 /** @{ */
346 int getSequenceCount() const
347 {
348 return sequenceCount;
349 }
350 void setSequenceCount(const int count);
351 /** @} */
352
353 /** @brief Number of captures completed in the associated sequence. */
354 /** @{ */
355 int getCompletedCount() const
356 {
357 return completedCount;
358 }
359 void setCompletedCount(const int count);
360 /** @} */
361
362 /** @brief Time at which the job must start. */
363 /** @{ */
364 QDateTime getStartupTime() const
365 {
366 return startupTime;
367 }
368 void setStartupTime(const QDateTime &value, bool refreshDawnDusk = true);
369 /** @} */
370
371 /** @brief Time after which the job is considered to finish. */
372 /** @{ */
373 QDateTime getFinishAtTime() const
374 {
375 return finishAtTime;
376 }
377 QDateTime getStopTime() const
378 {
379 return stopTime;
380 }
381 const QString &getStopReason() const
382 {
383 return stopReason;
384 }
385 void setStopReason(const QString &reason)
386 {
387 stopReason = reason;
388 }
389 void setFinishAtTime(const QDateTime &value);
390 /** @} */
391 void setStopTime(const QDateTime &value);
392
393 /** @brief Estimation of the time the job will take to process. */
394 /** @{ */
395 int64_t getEstimatedTime() const
396 {
397 return estimatedTime;
398 }
399 void setEstimatedTime(const int64_t &value);
400 /** @} */
401
402 /** @brief Estimation of the time the job will take to process each repeat. */
403 /** @{ */
404 int64_t getEstimatedTimePerRepeat() const
405 {
406 return estimatedTimePerRepeat;
407 }
408 void setEstimatedTimePerRepeat(const int64_t &value)
409 {
410 estimatedTimePerRepeat = value;
411 }
412
413 /** @brief Estimation of the time the job will take at startup. */
414 /** @{ */
415 int64_t getEstimatedStartupTime() const
416 {
417 if (m_LeadJob != nullptr)
418 return m_LeadJob->getEstimatedStartupTime();
419 else
420 return estimatedStartupTime;
421 }
422 void setEstimatedStartupTime(const int64_t &value)
423 {
424 estimatedStartupTime = value;
425 }
426
427 /** @brief Estimation of the time the job will take to process each repeat. */
428 /** @{ */
429 int64_t getEstimatedTimeLeftThisRepeat() const
430 {
431 return estimatedTimeLeftThisRepeat;
432 }
433 void setEstimatedTimeLeftThisRepeat(const int64_t &value)
434 {
435 estimatedTimeLeftThisRepeat = value;
436 }
437
438 /** @brief Whether this job requires light frames, or only calibration frames. */
439 /** @{ */
440 bool getLightFramesRequired() const
441 {
442 return lightFramesRequired;
443 }
444 void setLightFramesRequired(bool value);
445 /** @} */
446
447 /** @brief Whether this job contains a calibration job that requires mount parking. */
448 /** @{ */
449 bool getCalibrationMountPark() const
450 {
451 return m_CalibrationMountPark;
452 }
453 void setCalibrationMountPark(bool value);
454 /** @} */
455
456 /** @brief Number of times this job must be repeated (in terms of capture count). */
457 /** @{ */
458 uint16_t getRepeatsRequired() const
459 {
460 return repeatsRequired;
461 }
462 void setRepeatsRequired(const uint16_t &value);
463 /** @} */
464
465 /** @brief Number of times this job still has to be repeated (in terms of capture count). */
466 /** @{ */
467 uint16_t getRepeatsRemaining() const
468 {
469 return repeatsRemaining;
470 }
471 void setRepeatsRemaining(const uint16_t &value);
472 /** @} */
473
474 void clearProgress()
475 {
476 m_Progress.clear();
477 }
478 void addProgress(int numCompleted, const SequenceJob *job)
479 {
480 m_Progress.append(JobProgress(numCompleted, job));
481 }
482 /** @brief Human-readable summary of captures completed for this job. */
483 /** @{ */
484 const QString getProgressSummary() const;
485 /** @} */
486
487 /** @brief The map of capture counts for this job, keyed by its capture storage signatures. */
488 /** @{ */
489 const CapturedFramesMap &getCapturedFramesMap() const
490 {
491 return capturedFramesMap;
492 }
493 void setCapturedFramesMap(const CapturedFramesMap &value);
494 /** @} */
495
496 /** @brief Resetting a job to original values:
497 * - idle state and stage
498 * - original startup, none if asap, else user original setting
499 * - duration not estimated
500 * - full repeat count
501 */
502 void reset();
503
504 /** @brief Determining whether a SchedulerJob is a duplicate of another.
505 * @param a_job is the other SchedulerJob to test duplication against.
506 * @return True if objects are different, but name and sequence file are identical, else false.
507 * @warning This is a weak comparison, but that's what the scheduler looks at to decide completion.
508 */
509 bool isDuplicateOf(SchedulerJob const *a_job) const
510 {
511 return this != a_job && name == a_job->getName() && sequenceFile == a_job->sequenceFile;
512 }
513
514 /** @brief Compare ::SchedulerJob instances based on altitude and movement in sky at startup time.
515 * @todo This is a qSort predicate, deprecated in QT5.
516 * @arg a, b are ::SchedulerJob instances to compare.
517 * @arg when is the date/time to use to calculate the altitude to sort with, defaulting to a's startup time.
518 * @note To obtain proper sort between several SchedulerJobs, all should have the same startup time.
519 * @note Use std:bind to bind a specific date/time to this predicate for altitude calculation.
520 * @return true is a is setting but not b.
521 * @return false if b is setting but not a.
522 * @return true otherwise, if the altitude of b is lower than the altitude of a.
523 * @return false otherwise, if the altitude of b is higher than or equal to the altitude of a.
524 */
525 static bool decreasingAltitudeOrder(SchedulerJob const *a, SchedulerJob const *b, QDateTime const &when = QDateTime());
526
527 /**
528 * @brief moonSeparationOK return true if angle from target to the Moon is > minMoonSeparation
529 * @param when date and time to check the Moon separation, now if omitted.
530 * @return true if target is separated enough from the Moon.
531 */
532 bool moonSeparationOK(QDateTime const &when = QDateTime()) const;
533
534 /**
535 * @brief calculateNextTime calculate the next time constraints are met (or missed).
536 * @param when date and time to start searching from, now if omitted.
537 * @param constraintsAreMet if true, searches for the next time constrains are met, else missed.
538 * @return The date and time the target meets or misses constraints.
539 */
540 QDateTime calculateNextTime(QDateTime const &when, bool checkIfConstraintsAreMet = true, int increment = 1,
541 QString *reason = nullptr, bool runningJob = false, const QDateTime &until = QDateTime()) const;
542 QDateTime getNextPossibleStartTime(const QDateTime &when, int increment = 1, bool runningJob = false,
543 const QDateTime &until = QDateTime()) const;
544 QDateTime getNextEndTime(const QDateTime &start, int increment = 1, QString *reason = nullptr,
545 const QDateTime &until = QDateTime()) const;
546
547 /**
548 * @brief getNextAstronomicalTwilightDawn
549 * @return a local time QDateTime locating the first astronomical dawn after this observation.
550 * @note The dawn time takes into account the Ekos dawn offset.
551 */
552 QDateTime getDawnAstronomicalTwilight() const
553 {
554 if (m_LeadJob != nullptr)
555 return m_LeadJob->getDawnAstronomicalTwilight();
556 else
557 return nextDawn;
558 };
559
560 /**
561 * @brief getDuskAstronomicalTwilight
562 * @return a local-time QDateTime locating the first astronomical dusk after this observation.
563 * @note The dusk time takes into account the Ekos dusk offset.
564 */
565 QDateTime getDuskAstronomicalTwilight() const
566 {
567 if (m_LeadJob != nullptr)
568 return m_LeadJob->getDuskAstronomicalTwilight();
569 else
570 return nextDusk;
571 };
572
573 /**
574 * @brief runsDuringAstronomicalNightTime
575 * @param time uses the time given for the check, or, if not valid (the default) uses the job's startup time.
576 * @return true if the next dawn/dusk event after this observation is the astronomical dawn, else false.
577 * @note This function relies on the guarantee that dawn and dusk are calculated to be the first events after this observation.
578 */
579 bool runsDuringAstronomicalNightTime(const QDateTime &time = QDateTime(), QDateTime *nextPossibleSuccess = nullptr) const;
580
581 /**
582 * @brief satisfiesAltitudeConstraint sees if altitude is allowed for this job at the given azimuth.
583 * @param azimuth Azimuth
584 * @param altitude Altitude
585 * @param altitudeReason a human-readable string explaining why false was returned.
586 * @return true if this altitude is permissible for this job
587 */
588 bool satisfiesAltitudeConstraint(double azimuth, double altitude, QString *altitudeReason = nullptr) const;
589
590 /**
591 * @brief setInitialFilter Set initial filter used in the capture sequence. This is used to pass to focus module.
592 * @param value Filter name of FIRST LIGHT job in the sequence queue, if any.
593 */
594 void setInitialFilter(const QString &value);
595 const QString &getInitialFilter() const;
596
597 // Convenience debugging methods.
598 static QString jobStatusString(SchedulerJobStatus status);
599 static QString jobStageString(SchedulerJobStage stage);
600 QString jobStartupConditionString(StartupCondition condition) const;
601 QString jobCompletionConditionString(CompletionCondition condition) const;
602
603 // Clear the cache that keeps results for getNextPossibleStartTime().
604 void clearCache()
605 {
606 startTimeCache.clear();
607 }
608 double getAltitudeAtStartup() const
609 {
610 if (m_LeadJob != nullptr)
611 return m_LeadJob->getAltitudeAtStartup();
612 else
613 return altitudeAtStartup;
614 }
615 double getAltitudeAtStop() const
616 {
617 return altitudeAtStop;
618 }
619 bool isSettingAtStartup() const
620 {
621 if (m_LeadJob != nullptr)
622 return m_LeadJob->isSettingAtStartup();
623 else
624 return settingAtStartup;
625 }
626 bool isSettingAtStop() const
627 {
628 return settingAtStop;
629 }
630
631 SchedulerJob *leadJob() const
632 {
633 return m_LeadJob;
634 }
635 void setLeadJob(SchedulerJob *newLeadJob)
636 {
637 m_LeadJob = newLeadJob;
638 }
639
640 QList<SchedulerJob *> &followerJobs()
641 {
642 return m_followerJobs;
643 }
644
645 void setStartupFormatted(const QString &value)
646 {
647 m_StartupFormatted = value;
648 }
649 const QString &startupFormatted() const
650 {
651 return m_StartupFormatted;
652 }
653
654 void setEndFormatted(const QString &value)
655 {
656 m_EndFormatted = value;
657 }
658 const QString &endFormatted() const
659 {
660 return m_EndFormatted;
661 }
662
663 void setAltitudeFormatted(const QString &value)
664 {
665 m_AltitudeFormatted = value;
666 }
667 const QString &altitudeFormatted() const
668 {
669 return m_AltitudeFormatted;
670 }
671
672private:
673 bool runsDuringAstronomicalNightTimeInternal(const QDateTime &time, QDateTime *minDawnDusk,
674 QDateTime *nextPossibleSuccess = nullptr) const;
675
676 // Private constructor for unit testing.
677 SchedulerJob(KSMoon *moonPtr);
678 friend TestSchedulerUnit;
679 friend TestEkosSchedulerOps;
680
681 /** @brief Setter used in the unit test to fix the local time. Otherwise getter gets from KStars instance. */
682 /** @{ */
683 static KStarsDateTime getLocalTime();
684 /** @} */
685
686 /** @brief Setter used in testing to fix the artificial horizon. Otherwise getter gets from KStars instance. */
687 /** @{ */
688 static const ArtificialHorizon *getHorizon();
689 static void setHorizon(ArtificialHorizon *horizon)
690 {
691 storedHorizon = horizon;
692 }
693 static bool hasHorizon()
694 {
695 return storedHorizon != nullptr;
696 }
697
698 /** @} */
699
701 bool m_isLead { true };
702 QString group;
703 QString opticalTrain;
704 int completedIterations { 0 };
705 SkyPoint targetCoords;
706 double m_PositionAngle { -1 };
707 SchedulerJobStatus state { SCHEDJOB_IDLE };
708 SchedulerJobStage stage { SCHEDSTAGE_IDLE };
709
710 // leader / follower relationship
711 SchedulerJob *m_LeadJob { nullptr };
712 QList <SchedulerJob *> m_followerJobs;
713
714 // The time that the job stage was set.
715 // Used by the Greedy Algorithm to decide when to run JOB_ABORTED jobs again.
716 QDateTime stateTime;
717 QDateTime lastAbortTime;
718 QDateTime lastErrorTime;
719
720 StartupCondition fileStartupCondition { START_ASAP };
721 StartupCondition startupCondition { START_ASAP };
722 CompletionCondition completionCondition { FINISH_SEQUENCE };
723
724 int sequenceCount { 0 };
725 int completedCount { 0 };
726
727 // Defined startup time, used for the StartupCondition START_AT.
728 QDateTime startAtTime;
729 // Startup time calculated by the scheduler.
730 QDateTime startupTime;
731 // Completion constraint when the job must finish, used for the CompletionCondition FINISH_AT.
732 QDateTime finishAtTime;
733 // Next time when the scheduler will stop the job, either because its
734 // completed, its constraints aren't met or another job has higher priority.
735 QDateTime stopTime;
736 // The reason this job is stopping/will-be stopped.
737 QString stopReason;
738
739 /* @internal Caches to optimize cell rendering. */
740 /* @{ */
741 double altitudeAtStartup { 0 };
742 double altitudeAtStop { 0 };
743 bool settingAtStartup { false };
744 bool settingAtStop { false };
745 /* @} */
746
747 QUrl sequenceFile;
748 QUrl fitsFile;
749
750 double minAltitude { UNDEFINED_ALTITUDE };
751 double minMoonSeparation { -1 };
752
753 bool enforceWeather { false };
754 bool enforceTwilight { false };
755 bool enforceArtificialHorizon { false };
756
757 QDateTime nextDawn;
758 QDateTime nextDusk;
759
760 StepPipeline stepPipeline { USE_NONE };
761
762 int64_t estimatedTime { -1 };
763 int64_t estimatedTimePerRepeat { 0 };
764 int64_t estimatedStartupTime { 0 };
765 int64_t estimatedTimeLeftThisRepeat { 0 };
766 uint16_t repeatsRequired { 1 };
767 uint16_t repeatsRemaining { 1 };
768 bool inSequenceFocus { false };
769 QString m_InitialFilter;
770
771 QString dateTimeDisplayFormat;
772
773 QString m_StartupFormatted, m_EndFormatted, m_AltitudeFormatted;
774
775 bool lightFramesRequired { false };
776 bool m_CalibrationMountPark {false};
777
778 CapturedFramesMap capturedFramesMap;
779
780 /// Pointer to Moon object
781 KSMoon *moon { nullptr };
782
783 // Used to display human-readable job progress.
784 QList<JobProgress> m_Progress;
785
786 // This class is used to cache the results computed in getNextPossibleStartTime()
787 // which is called repeatedly by the Greedy scheduler.
788 // The cache would need to be cleared if something changes that would affect the
789 // start time of jobs (geography, altitide constraints) so it is reset at the start
790 // of all schedule calculations--which does not impact its effectiveness.
791 class StartTimeCache
792 {
793 // Keep track of calls to getNextPossibleStartTime, storing the when, until and result.
794 struct StartTimeComputation
795 {
796 QDateTime from;
797 QDateTime until;
798 QDateTime result;
799 };
800 public:
801 StartTimeCache() {}
802 // Check if the computation has been done, and if so, return the previous result.
803 bool check(const QDateTime &from, const QDateTime &until,
804 QDateTime *result, QDateTime *newFrom) const;
805 // Add a result to the cache.
806 void add(const QDateTime &from, const QDateTime &until, const QDateTime &result) const;
807 // Clear the cache.
808 void clear() const;
809 private:
810 // Made this mutable and all methods const so that the cache could be
811 // used in SchedulerJob const methods.
812 mutable QList<StartTimeComputation> startComputations;
813 };
814 StartTimeCache startTimeCache;
815
816 // These are used in testing, instead of KStars::Instance() resources
817 static KStarsDateTime *storedLocalTime;
818 static GeoLocation *storedGeo;
819 static ArtificialHorizon *storedHorizon;
820};
821} // Ekos namespace
Represents custom area from the horizon upwards which represent blocked views from the vantage point ...
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
Definition geolocation.h:28
Provides necessary information about the Moon.
Definition ksmoon.h:26
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
Sequence Job is a container for the details required to capture a series of images.
The sky coordinates of a point in the sky.
Definition skypoint.h:45
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
Ekos is an advanced Astrophotography tool for Linux.
Definition align.cpp:83
@ SCHEDJOB_ABORTED
Job encountered a transitory issue while processing, and will be rescheduled.
@ SCHEDJOB_IDLE
Job was just created, and is not evaluated yet.
QMap< QString, uint16_t > CapturedFramesMap
mapping signature --> frames count
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
QString name(StandardAction id)
KGuiItem properties()
void append(QList< T > &&value)
void clear()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:15:12 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.