From 31ff9a4b8fefed2050939298bdbd8302316c12d4 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Thu, 16 Jan 2014 12:21:29 +0200 Subject: [PATCH] Move main movie compatiblity checking to controller_frame_vector --- include/library/controller-data.hpp | 13 ++++++ include/library/movie.hpp | 10 +++++ src/library/controller-data.cpp | 61 +++++++++++++++++++++++++++++ src/library/movie.cpp | 58 +-------------------------- 4 files changed, 85 insertions(+), 57 deletions(-) diff --git a/include/library/controller-data.hpp b/include/library/controller-data.hpp index 21eab050..9c191cc0 100644 --- a/include/library/controller-data.hpp +++ b/include/library/controller-data.hpp @@ -696,6 +696,10 @@ public: * Get the frame parameters polled flag. */ bool get_framepflag() const throw(); +/** + * Get raw pollcounter data. + */ + const uint32_t* rawdata() const throw() { return ctrs; } private: uint32_t* ctrs; const port_type_set* types; @@ -1169,6 +1173,15 @@ public: * Get content of given page. */ const unsigned char* get_page_buffer(size_t page) const { return pages.find(page)->second.content; } +/** + * Check that the movies are compatible up to a point. + * + * Parameter with: The 2nd frame vector to check. + * Parameter frame: The frame number (1-based) to check to. + * Parameter polls: The poll counters within frame to check to. + * Returns: True if compatible, false if not. + */ + bool compatible(controller_frame_vector& with, uint64_t frame, const uint32_t* polls); /** * Notify sync flag polarity change. * diff --git a/include/library/movie.hpp b/include/library/movie.hpp index 0530301c..f9a62ee3 100644 --- a/include/library/movie.hpp +++ b/include/library/movie.hpp @@ -274,6 +274,16 @@ public: */ void write_subframe_at_index(uint32_t subframe, unsigned port, unsigned controller, unsigned index, int16_t x); +/** + * Call controller_frame_vector::compatible() with correct frame and pollcounters. + * + * Parameter with: The second vector. + * Returns: True if compatible, false if not. + */ + bool compatible(controller_frame_vector& with) + { + return movie_data.compatible(with, current_frame, pollcounters.rawdata()); + } private: //Sequence number. uint64_t seqno; diff --git a/src/library/controller-data.cpp b/src/library/controller-data.cpp index 5d360745..31a18381 100644 --- a/src/library/controller-data.cpp +++ b/src/library/controller-data.cpp @@ -243,6 +243,16 @@ namespace buf[i] = c[i]; return i; } + + uint64_t find_next_sync(controller_frame_vector& movie, uint64_t after) + { + if(after >= movie.size()) + return after; + do { + after++; + } while(after < movie.size() && !movie[after].sync()); + return after; + } } void controller_frame::display(unsigned port, unsigned controller, char32_t* buf) throw() @@ -637,6 +647,57 @@ void controller_frame_vector::resize(size_t newsize) throw(std::bad_alloc) } } +bool controller_frame_vector::compatible(controller_frame_vector& with, uint64_t frame, const uint32_t* polls) +{ + //Types have to match. + if(get_types() != with.get_types()) + return false; + const port_type_set& pset = with.get_types(); + //If new movie is before first frame, anything with same project_id is compatible. + if(frame == 0) + return true; + //Scan both movies until frame syncs are seen. Out of bounds reads behave as all neutral but frame + //sync done. + uint64_t syncs_seen = 0; + uint64_t frames_read = 0; + while(syncs_seen < frame - 1) { + controller_frame oldc = blank_frame(true), newc = with.blank_frame(true); + if(frames_read < size()) + oldc = (*this)[frames_read]; + if(frames_read < with.size()) + newc = with[frames_read]; + if(oldc != newc) + return false; //Mismatch. + frames_read++; + if(newc.sync()) + syncs_seen++; + } + //We increment the counter one time too many. + frames_read--; + //Current frame. We need to compare each control up to poll counter. + uint64_t readable_old_subframes = 0, readable_new_subframes = 0; + uint64_t oldlen = find_next_sync(*this, frames_read); + uint64_t newlen = find_next_sync(with, frames_read); + if(frames_read < oldlen) + readable_old_subframes = oldlen - frames_read; + if(frames_read < newlen) + readable_new_subframes = newlen - frames_read; + //Then rest of the stuff. + for(unsigned i = 0; i < pset.indices(); i++) { + uint32_t p = polls[i] & 0x7FFFFFFFUL; + short ov = 0, nv = 0; + for(uint32_t j = 0; j < p; j++) { + if(j < readable_old_subframes) + ov = (*this)[j + frames_read].axis2(i); + if(j < readable_new_subframes) + nv = with[j + frames_read].axis2(i); + if(ov != nv) + return false; + } + } + return true; +} + controller_frame::controller_frame() throw() { memset(memory, 0, sizeof(memory)); diff --git a/src/library/movie.cpp b/src/library/movie.cpp index 772a55f0..9c46f62f 100644 --- a/src/library/movie.cpp +++ b/src/library/movie.cpp @@ -11,16 +11,6 @@ namespace { - uint64_t find_next_sync(controller_frame_vector& movie, uint64_t after) - { - if(after >= movie.size()) - return after; - do { - after++; - } while(after < movie.size() && !movie[after].sync()); - return after; - } - bool movies_compatible(controller_frame_vector& old_movie, controller_frame_vector& new_movie, uint64_t frame, const uint32_t* polls, const std::string& old_projectid, const std::string& new_projectid) @@ -28,53 +18,7 @@ namespace //Project IDs have to match. if(old_projectid != new_projectid) return false; - //Types have to match. - if(old_movie.get_types() != new_movie.get_types()) - return false; - const port_type_set& pset = new_movie.get_types(); - //If new movie is before first frame, anything with same project_id is compatible. - if(frame == 0) - return true; - //Scan both movies until frame syncs are seen. Out of bounds reads behave as all neutral but frame - //sync done. - uint64_t syncs_seen = 0; - uint64_t frames_read = 0; - while(syncs_seen < frame - 1) { - controller_frame oldc = old_movie.blank_frame(true), newc = new_movie.blank_frame(true); - if(frames_read < old_movie.size()) - oldc = old_movie[frames_read]; - if(frames_read < new_movie.size()) - newc = new_movie[frames_read]; - if(oldc != newc) - return false; //Mismatch. - frames_read++; - if(newc.sync()) - syncs_seen++; - } - //We increment the counter one time too many. - frames_read--; - //Current frame. We need to compare each control up to poll counter. - uint64_t readable_old_subframes = 0, readable_new_subframes = 0; - uint64_t oldlen = find_next_sync(old_movie, frames_read); - uint64_t newlen = find_next_sync(new_movie, frames_read); - if(frames_read < oldlen) - readable_old_subframes = oldlen - frames_read; - if(frames_read < newlen) - readable_new_subframes = newlen - frames_read; - //Then rest of the stuff. - for(unsigned i = 0; i < pset.indices(); i++) { - uint32_t p = polls[i] & 0x7FFFFFFFUL; - short ov = 0, nv = 0; - for(uint32_t j = 0; j < p; j++) { - if(j < readable_old_subframes) - ov = old_movie[j + frames_read].axis2(i); - if(j < readable_new_subframes) - nv = new_movie[j + frames_read].axis2(i); - if(ov != nv) - return false; - } - } - return true; + return old_movie.compatible(new_movie, frame, polls); } }