Move main movie compatiblity checking to controller_frame_vector

This commit is contained in:
Ilari Liusvaara 2014-01-16 12:21:29 +02:00
parent a727d47a0c
commit 31ff9a4b8f
4 changed files with 85 additions and 57 deletions

View file

@ -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.
*

View file

@ -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;

View file

@ -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));

View file

@ -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);
}
}