Skip to content

Commit

Permalink
Simplify ChSequenceGenerator implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
oblivioncth committed Sep 30, 2024
1 parent edee5a9 commit 935ec24
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 54 deletions.
61 changes: 14 additions & 47 deletions lib/src/medium_io/sequence/ch_sequence_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,84 +15,53 @@ namespace PxCryptPrivate
//Public:
ChSequenceGenerator::ChSequenceGenerator(QByteArrayView seed) :
mGenerator(Qx::Integrity::crc32(seed)),
mStep(-1)
mUnusedChannels(ALL_CHANNELS.cbegin(), ALL_CHANNELS.cend())
{
Q_ASSERT(!seed.isEmpty());
reset();
}

ChSequenceGenerator::ChSequenceGenerator(const State& state) :
mGenerator(state.rng()),
mUsedChannels(state.channels()),
mStep(state.step())
mUnusedChannels(state.channels())
{}

//-Instance Functions--------------------------------------------------------------------------------------------
//Private:
void ChSequenceGenerator::reset()
{
mUsedChannels.fill(false);
mStep = -1; // Before 1st step, pushed to 0 by next
mUnusedChannels.append(ALL_CHANNELS.data(), ALL_CHANNELS.size());
}

//Public:
bool ChSequenceGenerator::pixelExhausted() const { return mStep == 2; }
int ChSequenceGenerator::step() const { return mStep; }
bool ChSequenceGenerator::pixelExhausted() const { return mUnusedChannels.isEmpty(); }

ChSequenceGenerator::State ChSequenceGenerator::state() const
{
return State{mGenerator, mUsedChannels, mStep};
return State{mGenerator, mUnusedChannels};
}

Channel ChSequenceGenerator::next()
{
// Reset if on new pixels
// Reset if on new pixel
if(pixelExhausted())
reset();

// Determine next channel
quint32 min;
for(uint i = Channel::Red; i <= Channel::Blue; i++)
{
if(!mUsedChannels[i])
{
min = i;
break;
}
}

quint32 max;
for(uint i = Channel::Blue; i >= Channel::Red; i--)
{
if(!mUsedChannels[i])
{
max = i;
break;
}
}

quint32 ch;
if(min == max) // Ignore warning about garbage value
ch = min;
else
{
do
ch = mGenerator.bounded(min, max + 1);
while(mUsedChannels[ch]);
}
auto rem = mUnusedChannels.size();
quint32 idx = rem == 1 ? 0 : mGenerator.bounded(rem);
Channel ch = mUnusedChannels[idx];

// Update state and return
mUsedChannels[ch] = true;
mStep++;
return static_cast<Channel>(ch);
mUnusedChannels.remove(idx);
return ch;
}

//-Operators----------------------------------------------------------------------------------------------------------------
//Public:
bool ChSequenceGenerator::operator==(const State& state) const
{
return mGenerator == state.rng() &&
mUsedChannels == state.channels();
mUnusedChannels == state.channels();
}

//===============================================================================================================
Expand All @@ -101,16 +70,14 @@ bool ChSequenceGenerator::operator==(const State& state) const

//-Constructor---------------------------------------------------------------------------------------------------------
//Public:
ChSequenceGenerator::State::State(const QRandomGenerator& rng, const ChannelTracker& channels, int step) :
ChSequenceGenerator::State::State(const QRandomGenerator& rng, const ChannelTracker& channels) :
mRng(rng),
mChannels(channels),
mStep(step)
mChannels(channels)
{}

//-Instance Functions--------------------------------------------------------------------------------------------
//Public:
QRandomGenerator ChSequenceGenerator::State::rng() const { return mRng; }
ChSequenceGenerator::ChannelTracker ChSequenceGenerator::State::channels() const { return mChannels; }
int ChSequenceGenerator::State::step() const { return mStep; }

}
15 changes: 8 additions & 7 deletions lib/src/medium_io/sequence/ch_sequence_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

// Qt Includes
#include <QRandomGenerator>
#include <QVarLengthArray>

// Project Includes
#include "codec/encdec.h"
Expand All @@ -17,17 +18,20 @@ class ChSequenceGenerator
{
//-Aliases----------------------------------------------------------------------------------------------------------
private:
using ChannelTracker = std::array<bool, CH_COUNT>;
using ChannelTracker = QVarLengthArray<Channel, 3>;

//-Inner Class------------------------------------------------------------------------------------------------------
public:
class State;

//-Class Variables------------------------------------------------------------------------------------------------------
private:
static constexpr std::array<Channel, 3> ALL_CHANNELS{Channel::Red, Channel::Green, Channel::Blue};

//-Instance Variables------------------------------------------------------------------------------------------------------
private:
QRandomGenerator mGenerator;
ChannelTracker mUsedChannels; // Wastes 1 element slot, but keeps indexing clean
int mStep;
ChannelTracker mUnusedChannels;

//-Constructor---------------------------------------------------------------------------------------------------------
public:
Expand All @@ -40,7 +44,6 @@ class ChSequenceGenerator

public:
bool pixelExhausted() const;
int step() const;
State state() const;

Channel next();
Expand All @@ -56,17 +59,15 @@ class ChSequenceGenerator::State
private:
QRandomGenerator mRng;
ChannelTracker mChannels;
int mStep;

//-Constructor-------------------------------------------------------------------------------------------------------------
public:
State(const QRandomGenerator& rng, const ChannelTracker& channels, int step);
State(const QRandomGenerator& rng, const ChannelTracker& channels);

//-Instance Functions------------------------------------------------------------------------------------------------------
public:
QRandomGenerator rng() const;
ChannelTracker channels() const;
int step() const;
};

}
Expand Down
Binary file modified test/consistent_rng/data/encoded_qt_6-7-2_msvc2022.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 935ec24

Please sign in to comment.