ofxImageSequence independent instances

Hi,

I just started using ofxImageSequence in a project.
I need to have different copies of the same sequence playing independently.
To save resources, I implemented it with shared pointers. The idea is to have a library of sequences in memory that can be replicated but played independently. So having different objects using the same frames (images in the sequence) but at different times, rates and loop modes.

My problem emerges when I make a copy of the object in the library. Every copy of that object is affected when I tweak any of the other copies of the same object. So, if I run .play() on one copy, all the other copies that are using the same sequence will start playing.

I peeked into the source code of ofxImageSequence and found that it uses a pointer to reference the images. So I reckon that’s what’s troubling me. Is there a way around this? The only solution I’ve found so far is loading the images again for each object, which would eventually build up in a bloat of copies of the same images.

Following is a proof of concept for the code.

#pragma once

#include "ofMain.h"
#include "imagesequence.h" // just a wraper  of ofxImageWrapperPlayback with a few extras
class ofApp : public ofBaseApp{

public:
    void setup();
    void update();
    void draw();

    ofPlanePrimitive plane1;
    ofPlanePrimitive plane2;
    ofTexture tex1;
    ofTexture tex2;
    ofEasyCam cam;
    shared_ptr<ImageSequence> seq1;
    shared_ptr<ImageSequence> seq2;
};

// ofApp.cpp
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    ofEnableDepthTest();

    ofDisableArbTex();
    seq1 = make_shared<ImageSequence>();
    seq2 = make_shared<ImageSequence>();
    seq1->loadSequence("imgs/mama", 24.0f);
    *seq2 = *seq1;
    seq1->setShouldLoop(true);
    seq2->setShouldPingPong(true);
    seq1->play();
    seq2->stop();

    ofSetLogLevel(OF_LOG_VERBOSE);
}

//--------------------------------------------------------------
void ofApp::update(){
    seq1->update();
    seq2->update();
    tex1 = seq1->getTextureForFrame(seq1->getCurrentFrameIndex());
    tex2 = seq2->getTextureForFrame(seq2->getCurrentFrameIndex());
}

//--------------------------------------------------------------
void ofApp::draw(){
    cam.begin();
    tex1.bind();
    plane1.draw();
    tex1.unbind();

    tex2.bind();
    ofPushMatrix();
    ofTranslate(200,0,0);
    plane2.draw();
    ofPopMatrix();
    tex2.unbind();

    cam.end();
}

Hi, the behaviour you describe is expectable since you are calling *seq2 = *seq1; which make seq2 and seq1 to be esentially the same object. Making these to be shared pointers does not mean that only the data will be shared, but it means that everything is shared. you might need to implement your own class which allows you to share the collection of images but not the object’s playback state

1 Like

Oh, that actually makes total sense. Thanks!