Swapable variables

Just a small code that I use for some swapable variables, such as audio or other things that I want to mess with while everything is running. EG: load a new audio while the previous audio is still playing, no interruptions.

Please, if you find this stupid be nice and explain why so I can learn. :wink: I’m a very old “guru” programmer, but I suffer from mental problems, so sometimes I miss the little things…

Here’s an example on how I would use this for audio. I declare:

WusikSwapable originalAudio;

Now I get get the current playiung one with

originalAudio.getCurrent();

And the other one with

originalAudio.getOther();

When I’m ready to swamp each other I call

originalAudio.readyToSwap();

And in the processor block, before anything else I call

originalAudio.check();

This way I can load something to the next buffer without disrupting the audio and while keeping a copy of the previous buffer at all times and also while having just one code to handle how the audio plays.

template <class WType>
class WusikSwapable
{
public:
	WusikSwapable() 
	{ 
		current = 0;
		swap = false;
	};
	//
	void readyToSwap() { swap = true; }
	//
	WType& getCurrent()
	{
		return variables[current];
	}
	//
	WType& getOther()
	{
		return variables[1 - current];
	}
	//
	bool check()
	{
		if (swap)
		{
			current = 1 - current;
			swap = false;
			return true;
		}
		//
		return false;
	}
	//
	bool getSwap() { return swap; }
	//
private:
	WType variables[2];
	int current;
	bool swap;
};

What’s wrong with std::swap?

std::unique_ptr<MyNewComplexObject> newObject = createNewObject();

{
    SpinLock::ScopedLockType sl(lock); // Or whatever type of locking mechanism you use...
    std::swap(newObject, currentlyUsedObject);
}

// the old object will get deleted here.

Well, it doesn’t do what my code does, and doesn’t do what I need. :wink: As I said, let’s say I have some Audio Buffer that has the audio I want to playback. With my class above I can just add another audio, mark to be swaped when possible, and everything just works. std:swap just swaps a pointer, totally useless for my needs.

Cheers, WilliamK

But this means that you’re checking the variable in every render callback, which adds unnecessary branching. If you’re using lots of objects this might add some non-trivial performance overhead.

The other solution has absolutely no branching overhead, the only performance risk is a priority inversion for the short period of time while the lock is held by another thread for the swap operation.

Yeah, indeed, thanks. But, for my case is just two variables I’m using, and not often, so it should be ok.

I would rather use a local scoped shared_ptr that copy the member one during the process call so it has it’s own copy.
And you could switch the member one directly.
Still you need to have a custom dtor for this shared_ptr with a delete pool so the delete is not done in the audio thread