From: Mikko Rasa Date: Fri, 8 Nov 2013 18:27:18 +0000 (+0200) Subject: Move further stuff from the ArduControl main class into Task classes X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=8935c058a29ce263f4539832049aa74be3762438;p=r2c2.git Move further stuff from the ArduControl main class into Task classes --- diff --git a/source/libr2c2/arducontrol.cpp b/source/libr2c2/arducontrol.cpp index d18dc97..201d9a2 100644 --- a/source/libr2c2/arducontrol.cpp +++ b/source/libr2c2/arducontrol.cpp @@ -19,12 +19,9 @@ ArduControl::ArduControl(const string &dev): serial(dev), debug(1), power(false), - next_refresh(refresh_cycle.end()), - refresh_counter(0), active_accessory(0), - n_s88_octets(0), - mfx_announce_serial(0), - next_mfx_address(1), + s88(*this), + mfx_search(*this), thread(*this) { PendingCommand cmd; @@ -105,7 +102,7 @@ unsigned ArduControl::add_loco(unsigned addr, const string &proto_name, const Ve void ArduControl::remove_loco(unsigned id) { Locomotive &loco = get_item(locomotives, id); - remove_loco_from_refresh(loco); + refresh.remove_loco(loco); locomotives.erase(id); } @@ -120,7 +117,7 @@ void ArduControl::set_loco_speed(unsigned id, unsigned speed) PendingCommand cmd(loco, Locomotive::SPEED); push_command(cmd); - add_loco_to_refresh(loco); + refresh.add_loco(loco); } } @@ -132,7 +129,7 @@ void ArduControl::set_loco_reverse(unsigned id, bool rev) PendingCommand cmd(loco, Locomotive::REVERSE); push_command(cmd); - add_loco_to_refresh(loco); + refresh.add_loco(loco); } } @@ -151,64 +148,7 @@ void ArduControl::set_loco_function(unsigned id, unsigned func, bool state) push_command(cmd); } - add_loco_to_refresh(loco); - } -} - -void ArduControl::add_loco_to_refresh(Locomotive &loco) -{ - MutexLock lock(mutex); - refresh_cycle.push_back(&loco); - if(refresh_cycle.size()>15) - { - LocomotivePtrList::iterator oldest = refresh_cycle.begin(); - for(LocomotivePtrList::iterator i=refresh_cycle.begin(); ++i!=refresh_cycle.end(); ) - if((*i)->last_change_age>(*oldest)->last_change_age) - oldest = i; - if(oldest==next_refresh) - advance_next_refresh(); - refresh_cycle.erase(oldest); - } - if(next_refresh==refresh_cycle.end()) - next_refresh = refresh_cycle.begin(); -} - -void ArduControl::remove_loco_from_refresh(Locomotive &loco) -{ - MutexLock lock(mutex); - for(LocomotivePtrList::iterator i=refresh_cycle.begin(); i!=refresh_cycle.end(); ++i) - if(*i==&loco) - { - if(i==next_refresh) - { - if(refresh_cycle.size()>1) - advance_next_refresh(); - else - next_refresh = refresh_cycle.end(); - } - refresh_cycle.erase(i); - return; - } -} - -ArduControl::Locomotive *ArduControl::get_loco_to_refresh() -{ - MutexLock lock(mutex); - if(refresh_cycle.empty()) - return 0; - - Locomotive *loco = *next_refresh; - advance_next_refresh(); - return loco; -} - -void ArduControl::advance_next_refresh() -{ - ++next_refresh; - if(next_refresh==refresh_cycle.end()) - { - next_refresh = refresh_cycle.begin(); - ++refresh_counter; + refresh.add_loco(loco); } } @@ -307,9 +247,7 @@ unsigned ArduControl::add_sensor(unsigned addr) throw invalid_argument("ArduControl::add_sensor"); insert_unique(sensors, addr, Sensor(addr)); - unsigned octet_index = (addr-1)/8; - if(octet_index>=n_s88_octets) - n_s88_octets = octet_index+1; + s88.grow_n_octets((addr+7)/8); return addr; } @@ -317,7 +255,7 @@ unsigned ArduControl::add_sensor(unsigned addr) void ArduControl::remove_sensor(unsigned addr) { remove_existing(sensors, addr); - // TODO update n_s88_octets + // TODO update s88.n_octets } bool ArduControl::get_sensor(unsigned addr) const @@ -637,8 +575,9 @@ ArduControl::PendingCommand::PendingCommand(Accessory &acc, Accessory::Command c } -ArduControl::RefreshTask::RefreshTask(ArduControl &c): - control(c), +ArduControl::RefreshTask::RefreshTask(): + next(cycle.end()), + round(0), loco(0), phase(0) { } @@ -647,13 +586,13 @@ bool ArduControl::RefreshTask::get_work(PendingCommand &cmd) { if(loco && loco->proto==MM && phase==0) { - cmd.length = loco->create_speed_func_command(control.refresh_counter%4+1, cmd.command); + cmd.length = loco->create_speed_func_command(round%4+1, cmd.command); cmd.repeat_count = 2; ++phase; return true; } - loco = control.get_loco_to_refresh(); + loco = get_next_loco(); if(!loco) return false; @@ -671,21 +610,79 @@ bool ArduControl::RefreshTask::get_work(PendingCommand &cmd) return true; } +void ArduControl::RefreshTask::add_loco(Locomotive &l) +{ + MutexLock lock(mutex); + cycle.push_back(&l); + if(cycle.size()>15) + { + LocomotivePtrList::iterator oldest = cycle.begin(); + for(LocomotivePtrList::iterator i=cycle.begin(); ++i!=cycle.end(); ) + if((*i)->last_change_age>(*oldest)->last_change_age) + oldest = i; + if(oldest==next) + advance(); + cycle.erase(oldest); + } + if(next==cycle.end()) + next = cycle.begin(); +} + +void ArduControl::RefreshTask::remove_loco(Locomotive &l) +{ + MutexLock lock(mutex); + for(LocomotivePtrList::iterator i=cycle.begin(); i!=cycle.end(); ++i) + if(*i==&l) + { + if(i==next) + { + if(cycle.size()>1) + advance(); + else + next = cycle.end(); + } + cycle.erase(i); + return; + } +} + +ArduControl::Locomotive *ArduControl::RefreshTask::get_next_loco() +{ + MutexLock lock(mutex); + if(cycle.empty()) + return 0; + + Locomotive *l = *next; + advance(); + return l; +} + +void ArduControl::RefreshTask::advance() +{ + ++next; + if(next==cycle.end()) + { + next= cycle.begin(); + ++round; + } +} + ArduControl::S88Task::S88Task(ArduControl &c): control(c), + n_octets(0), octets_remaining(0) { } bool ArduControl::S88Task::get_work(PendingCommand &cmd) { - if(octets_remaining || !control.n_s88_octets) + if(octets_remaining || !n_octets) return false; + octets_remaining = n_octets; cmd.command[0] = S88_READ; - cmd.command[1] = control.n_s88_octets; + cmd.command[1] = octets_remaining; cmd.length = 2; - octets_remaining = control.n_s88_octets; return true; } @@ -721,9 +718,20 @@ void ArduControl::S88Task::process_reply(const char *reply, unsigned length) } } +void ArduControl::S88Task::set_n_octets(unsigned n) +{ + n_octets = n; +} + +void ArduControl::S88Task::grow_n_octets(unsigned n) +{ + if(n>n_octets) + n_octets = n; +} -ArduControl::MfxAnnounceTask::MfxAnnounceTask(ArduControl &c): - control(c) + +ArduControl::MfxAnnounceTask::MfxAnnounceTask(): + serial(0) { } bool ArduControl::MfxAnnounceTask::get_work(PendingCommand &cmd) @@ -733,17 +741,23 @@ bool ArduControl::MfxAnnounceTask::get_work(PendingCommand &cmd) return false; cmd.command[0] = MFX_ANNOUNCE; - cmd.command[1] = control.mfx_announce_serial>>8; - cmd.command[2] = control.mfx_announce_serial; + cmd.command[1] = serial>>8; + cmd.command[2] = serial; cmd.length = 3; next = t+400*Time::msec; return true; } +void ArduControl::MfxAnnounceTask::set_serial(unsigned s) +{ + serial = s; +} + ArduControl::MfxSearchTask::MfxSearchTask(ArduControl &c): control(c), + next_address(1), size(0), bits(0), pending(false) @@ -754,18 +768,18 @@ bool ArduControl::MfxSearchTask::get_work(PendingCommand &cmd) if(size==32) { if(control.debug>=1) - IO::print("Assigning MFX address %d to decoder %08X\n", control.next_mfx_address, bits); + IO::print("Assigning MFX address %d to decoder %08X\n", next_address, bits); cmd.command[0] = MFX_ASSIGN_ADDRESS; - cmd.command[1] = control.next_mfx_address>>8; - cmd.command[2] = control.next_mfx_address; + cmd.command[1] = next_address>>8; + cmd.command[2] = next_address; for(unsigned i=0; i<4; ++i) cmd.command[3+i] = bits>>(24-i*8); cmd.length = 7; size = 0; bits = 0; - ++control.next_mfx_address; + ++next_address; return true; } @@ -826,10 +840,10 @@ ArduControl::ControlThread::ControlThread(ArduControl &c): control(c), done(false) { - tasks.push_back(new MfxAnnounceTask(control)); - tasks.push_back(new MfxSearchTask(control)); - tasks.push_back(new S88Task(control)); - tasks.push_back(new RefreshTask(control)); + tasks.push_back(&control.mfx_announce); + tasks.push_back(&control.mfx_search); + tasks.push_back(&control.s88); + tasks.push_back(&control.refresh); launch(); } diff --git a/source/libr2c2/arducontrol.h b/source/libr2c2/arducontrol.h index d794d00..e354ecf 100644 --- a/source/libr2c2/arducontrol.h +++ b/source/libr2c2/arducontrol.h @@ -193,20 +193,32 @@ private: class RefreshTask: public Task { private: - ArduControl &control; + typedef std::list LocomotivePtrList; + + LocomotivePtrList cycle; + LocomotivePtrList::iterator next; + unsigned round; Locomotive *loco; unsigned phase; + Msp::Mutex mutex; public: - RefreshTask(ArduControl &); + RefreshTask(); virtual bool get_work(PendingCommand &); + + void add_loco(Locomotive &); + void remove_loco(Locomotive &); + private: + Locomotive *get_next_loco(); + void advance(); }; class S88Task: public Task { private: ArduControl &control; + unsigned n_octets; unsigned octets_remaining; public: @@ -214,24 +226,30 @@ private: virtual bool get_work(PendingCommand &); virtual void process_reply(const char *, unsigned); + + void set_n_octets(unsigned); + void grow_n_octets(unsigned); }; class MfxAnnounceTask: public Task { private: - ArduControl &control; + unsigned serial; Msp::Time::TimeStamp next; public: - MfxAnnounceTask(ArduControl &); + MfxAnnounceTask(); virtual bool get_work(PendingCommand &); + + void set_serial(unsigned); }; class MfxSearchTask: public Task { private: ArduControl &control; + unsigned next_address; Msp::Time::TimeStamp next; unsigned size; unsigned bits; @@ -263,7 +281,6 @@ private: }; typedef std::map LocomotiveMap; - typedef std::list LocomotivePtrList; typedef std::map AccessoryMap; typedef std::list AccessoryPtrList; typedef std::map SensorMap; @@ -274,9 +291,6 @@ private: ControlledVariable power; LocomotiveMap locomotives; - LocomotivePtrList refresh_cycle; - LocomotivePtrList::iterator next_refresh; - unsigned refresh_counter; AccessoryMap accessories; AccessoryPtrList accessory_queue; Accessory *active_accessory; @@ -285,12 +299,12 @@ private: std::list completed_commands; SensorMap sensors; - unsigned n_s88_octets; - - unsigned mfx_announce_serial; - unsigned next_mfx_address; Msp::Mutex mutex; + RefreshTask refresh; + S88Task s88; + MfxAnnounceTask mfx_announce; + MfxSearchTask mfx_search; ControlThread thread; static ProtocolInfo protocol_info[2]; @@ -315,13 +329,7 @@ public: virtual void set_loco_speed(unsigned, unsigned); virtual void set_loco_reverse(unsigned, bool); virtual void set_loco_function(unsigned, unsigned, bool); -private: - void add_loco_to_refresh(Locomotive &); - void remove_loco_from_refresh(Locomotive &); - Locomotive *get_loco_to_refresh(); - void advance_next_refresh(); -public: virtual unsigned add_turnout(unsigned, const TrackType &); virtual void remove_turnout(unsigned); virtual void set_turnout(unsigned, unsigned);