]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/arducontrol.h
Improve ArduControl task scheduling
[r2c2.git] / source / libr2c2 / arducontrol.h
index 1f45534a1ca472ee22cfbd40159fe2be806cf7a7..c170e4203c9c2eb3de864de49d958a0a10b6e794 100644 (file)
@@ -117,6 +117,7 @@ private:
 
                bool set(T v) { if(v==pending) return false; pending = v; ++serial; return true; }
                bool commit(unsigned short s) { if(s!=serial) return false; current = pending; return true; }
+               void rollback() { pending = current; ++serial; }
 
                operator T() const { return current; }
        };
@@ -172,11 +173,13 @@ private:
                Kind kind;
                unsigned address;
                unsigned bits;
+               unsigned valid_states;
                ControlledVariable<unsigned> state;
+               unsigned uncertain;
                unsigned target;
                Msp::Time::TimeDelta active_time;
 
-               Accessory(Kind, unsigned, unsigned);
+               Accessory(Kind, unsigned, unsigned, unsigned);
 
                unsigned create_state_command(unsigned, bool, char *) const;
        };
@@ -217,17 +220,29 @@ private:
        public:
                void push(const T &);
                bool pop(T &);
+               bool empty() const;
        };
 
        class Task
        {
        protected:
-               Task() { }
+               std::string name;
+               unsigned priority;
+               Msp::Time::TimeStamp sleep_timeout;
+
+               Task(const std::string &, unsigned = 0);
        public:
                virtual ~Task() { }
 
+               const std::string &get_name() const { return name; }
+
                virtual bool get_work(PendingCommand &) = 0;
                virtual void process_reply(const char *, unsigned) { }
+
+               unsigned get_priority() const { return priority; }
+               const Msp::Time::TimeStamp &get_sleep_timeout() const { return sleep_timeout; }
+       protected:
+               void sleep(const Msp::Time::TimeDelta &);
        };
 
        class CommandQueueTask: public Task
@@ -236,7 +251,12 @@ private:
                Queue<PendingCommand> queue;
 
        public:
+               CommandQueueTask();
+
                virtual bool get_work(PendingCommand &);
+
+               void push(const PendingCommand &);
+               bool empty() const { return queue.empty(); }
        };
 
        class RefreshTask: public Task
@@ -284,7 +304,6 @@ private:
        {
        private:
                unsigned serial;
-               Msp::Time::TimeStamp next;
 
        public:
                MfxAnnounceTask();
@@ -300,7 +319,6 @@ private:
        private:
                ArduControl &control;
                unsigned next_address;
-               Msp::Time::TimeStamp next;
                unsigned size;
                unsigned bits;
                unsigned misses;
@@ -316,6 +334,27 @@ private:
                bool pop_info(MfxInfo &);
        };
 
+       class MonitorTask: public Task
+       {
+       private:
+               float voltage;
+               float current;
+               float base_level;
+               float peak_level;
+               unsigned next_type;
+
+       public:
+               MonitorTask();
+
+               virtual bool get_work(PendingCommand &);
+               virtual void process_reply(const char *, unsigned);
+
+               float get_voltage() const { return voltage; }
+               float get_current() const { return current; }
+               void reset_peak();
+               float get_peak() const { return peak_level-base_level; }
+       };
+
        class ControlThread: public Msp::Thread
        {
        private:
@@ -331,8 +370,9 @@ private:
                virtual void main();
                void init_baud_rate();
                bool get_work(PendingCommand &);
-               unsigned do_command(const PendingCommand &);
+               unsigned do_command(const PendingCommand &, const Msp::Time::TimeDelta &);
                unsigned process_reply(const char *, unsigned);
+               void set_power(bool);
        };
 
        typedef std::map<unsigned, Locomotive> LocomotiveMap;
@@ -346,35 +386,38 @@ private:
        Msp::FS::Path state_file;
 
        ControlledVariable<bool> power;
+       bool halted;
 
        LocomotiveMap locomotives;
        MfxInfoArray mfx_info;
        AccessoryMap accessories;
        AccessoryPtrList accessory_queue;
        Accessory *active_accessory;
+       unsigned char active_index;
        Msp::Time::TimeStamp off_timeout;
 
        SensorMap sensors;
 
-       Msp::Mutex mutex;
-       Queue<PendingCommand> command_queue;
+       Msp::Time::TimeDelta command_timeout;
+       CommandQueueTask command_queue;
        Queue<Tag> completed_commands;
        RefreshTask refresh;
        S88Task s88;
        MfxAnnounceTask mfx_announce;
        MfxSearchTask mfx_search;
+       MonitorTask monitor;
        ControlThread thread;
 
        static ProtocolInfo protocol_info[2];
 
 public:
-       ArduControl(const std::string &);
+       ArduControl(const Options &);
        ~ArduControl();
 
        virtual void set_power(bool);
        virtual bool get_power() const { return power; }
        virtual void halt(bool);
-       virtual bool is_halted() const { return false; }
+       virtual bool is_halted() const { return halted; }
 
        virtual const char *enumerate_protocols(unsigned) const;
 private:
@@ -403,10 +446,11 @@ public:
        virtual unsigned get_signal(unsigned) const;
 
 private:
-       unsigned add_accessory(Accessory::Kind, unsigned, unsigned);
+       unsigned add_accessory(Accessory::Kind, unsigned, unsigned, unsigned);
        void remove_accessory(Accessory::Kind, unsigned);
        void set_accessory(Accessory::Kind, unsigned, unsigned);
        unsigned get_accessory(Accessory::Kind, unsigned) const;
+       void activate_accessory_by_mask(Accessory &, unsigned);
 
 public:
        virtual unsigned add_sensor(unsigned);