speed up loading of film simulation cluts by using one shared TreeModel for all the combo boxes

This commit is contained in:
Alberto Griggio
2017-10-13 23:06:52 +02:00
parent 1a046611cf
commit 2956be333b
2 changed files with 118 additions and 30 deletions

View File

@@ -62,8 +62,8 @@ bool notifySlowParseDir (const std::chrono::system_clock::time_point& startedAt)
FilmSimulation::FilmSimulation() FilmSimulation::FilmSimulation()
: FoldableToolPanel( this, "filmsimulation", M("TP_FILMSIMULATION_LABEL"), false, true ) : FoldableToolPanel( this, "filmsimulation", M("TP_FILMSIMULATION_LABEL"), false, true )
{ {
m_clutComboBox = Gtk::manage( new ClutComboBox() ); m_clutComboBox = Gtk::manage( new ClutComboBox(options.clutsDir) );
int foundClutsCount = m_clutComboBox->fillFromDir( options.clutsDir ); int foundClutsCount = m_clutComboBox->foundClutsCount();
if ( foundClutsCount == 0 ) { if ( foundClutsCount == 0 ) {
pack_start( *Gtk::manage( new Gtk::Label( M("TP_FILMSIMULATION_ZEROCLUTSFOUND") ) ) ); pack_start( *Gtk::manage( new Gtk::Label( M("TP_FILMSIMULATION_ZEROCLUTSFOUND") ) ) );
@@ -117,7 +117,7 @@ void FilmSimulation::adjusterChanged( Adjuster* a, double newval )
void FilmSimulation::setBatchMode( bool batchMode ) void FilmSimulation::setBatchMode( bool batchMode )
{ {
ToolPanel::setBatchMode( batchMode ); ToolPanel::setBatchMode( batchMode );
m_clutComboBox->addUnchangedEntry(); m_clutComboBox->setBatchMode(batchMode);
} }
void FilmSimulation::read( const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited ) void FilmSimulation::read( const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited )
@@ -197,27 +197,100 @@ void FilmSimulation::trimValues( rtengine::procparams::ProcParams* pp )
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
std::unique_ptr<ClutComboBox::ClutModel> ClutComboBox::cm;
std::unique_ptr<ClutComboBox::ClutModel> ClutComboBox::cm2;
ClutComboBox::ClutComboBox(const Glib::ustring &path):
MyComboBox(),
batchMode(false)
{
if (!cm) {
cm.reset(new ClutModel(path));
}
if (!cm2 && options.multiDisplayMode) {
cm2.reset(new ClutModel(path));
}
set_model(m_model());
if (cm->count > 0) {
pack_start(m_columns().label, false);
}
if (!options.multiDisplayMode) {
signal_map().connect(sigc::mem_fun(*this, &ClutComboBox::updateUnchangedEntry));
}
}
inline Glib::RefPtr<Gtk::TreeStore> &ClutComboBox::m_model()
{
if (!batchMode || !options.multiDisplayMode) {
return cm->m_model;
} else {
return cm2->m_model;
}
}
inline ClutComboBox::ClutColumns &ClutComboBox::m_columns()
{
if (!batchMode || !options.multiDisplayMode) {
return cm->m_columns;
} else {
return cm2->m_columns;
}
}
void ClutComboBox::setBatchMode(bool yes)
{
if (batchMode != yes) {
batchMode = yes;
set_model(m_model());
if (batchMode && options.multiDisplayMode) {
updateUnchangedEntry();
}
}
}
void ClutComboBox::updateUnchangedEntry()
{
auto c = m_model()->children();
if (batchMode) {
if (c.empty() || c[c.size()-1][m_columns().clutFilename] != "NULL") {
Gtk::TreeModel::Row row = *(m_model()->append());
row[m_columns().label] = M("GENERAL_UNCHANGED");
row[m_columns().clutFilename] = "NULL";
}
} else {
if (c.size() > 0) {
Gtk::TreeModel::Row row = c[c.size()-1];
if (row[m_columns().clutFilename] == "NULL") {
std::cout << " removing " << ((void *)this) << std::endl;
m_model()->erase(row);
}
}
}
}
ClutComboBox::ClutColumns::ClutColumns() ClutComboBox::ClutColumns::ClutColumns()
{ {
add( label ); add( label );
add( clutFilename ); add( clutFilename );
} }
int ClutComboBox::fillFromDir (const Glib::ustring& path) ClutComboBox::ClutModel::ClutModel(const Glib::ustring &path)
{ {
m_model = Gtk::TreeStore::create (m_columns); m_model = Gtk::TreeStore::create (m_columns);
set_model (m_model); //set_model (m_model);
count = parseDir(path);
const auto result = parseDir (path);
if (result > 0) {
pack_start (m_columns.label, false);
} }
return result; int ClutComboBox::ClutModel::parseDir(const Glib::ustring& path)
}
int ClutComboBox::parseDir(const Glib::ustring& path)
{ {
if (path.empty() || !Glib::file_test(path, Glib::FILE_TEST_IS_DIR)) { if (path.empty() || !Glib::file_test(path, Glib::FILE_TEST_IS_DIR)) {
return 0; return 0;
@@ -327,6 +400,11 @@ int ClutComboBox::parseDir(const Glib::ustring& path)
return fileCount; return fileCount;
} }
int ClutComboBox::foundClutsCount() const
{
return cm->count;
}
Glib::ustring ClutComboBox::getSelectedClut() Glib::ustring ClutComboBox::getSelectedClut()
{ {
Glib::ustring result; Glib::ustring result;
@@ -334,7 +412,7 @@ Glib::ustring ClutComboBox::getSelectedClut()
Gtk::TreeModel::Row row = *current; Gtk::TreeModel::Row row = *current;
if ( row ) { if ( row ) {
result = row[ m_columns.clutFilename ]; result = row[ m_columns().clutFilename ];
} }
return result; return result;
@@ -343,7 +421,7 @@ Glib::ustring ClutComboBox::getSelectedClut()
void ClutComboBox::setSelectedClut( Glib::ustring filename ) void ClutComboBox::setSelectedClut( Glib::ustring filename )
{ {
if ( !filename.empty() ) { if ( !filename.empty() ) {
Gtk::TreeIter found = findRowByClutFilename( m_model->children(), filename ); Gtk::TreeIter found = findRowByClutFilename( m_model()->children(), filename );
if ( found ) { if ( found ) {
set_active( found ); set_active( found );
@@ -358,7 +436,7 @@ Gtk::TreeIter ClutComboBox::findRowByClutFilename( Gtk::TreeModel::Children chil
for( Gtk::TreeModel::Children::iterator it = childs.begin(); !result && it != childs.end(); ++it ) { for( Gtk::TreeModel::Children::iterator it = childs.begin(); !result && it != childs.end(); ++it ) {
Gtk::TreeModel::Row row = *it; Gtk::TreeModel::Row row = *it;
if ( row[ m_columns.clutFilename ] == filename ) { if ( row[ m_columns().clutFilename ] == filename ) {
result = it; result = it;
} else { } else {
result = findRowByClutFilename( it->children(), filename ); result = findRowByClutFilename( it->children(), filename );
@@ -367,10 +445,3 @@ Gtk::TreeIter ClutComboBox::findRowByClutFilename( Gtk::TreeModel::Children chil
return result; return result;
} }
void ClutComboBox::addUnchangedEntry()
{
Gtk::TreeModel::Row row = *(m_model->append());
row[m_columns.label] = M("GENERAL_UNCHANGED");
row[m_columns.clutFilename] = "NULL";
}

View File

@@ -11,12 +11,16 @@
class ClutComboBox : public MyComboBox class ClutComboBox : public MyComboBox
{ {
public: public:
int fillFromDir (const Glib::ustring& path); ClutComboBox(const Glib::ustring &path);
//int fillFromDir (const Glib::ustring& path);
int foundClutsCount() const;
Glib::ustring getSelectedClut(); Glib::ustring getSelectedClut();
void setSelectedClut( Glib::ustring filename ); void setSelectedClut( Glib::ustring filename );
void addUnchangedEntry(); void setBatchMode(bool yes);
private: private:
void updateUnchangedEntry(); // in batchMode we need to add an extra entry "(Unchanged)". We do this whenever the widget is mapped (connecting to signal_map()), unless options.multiDisplayMode (see the comment below about cm2 in this case)
class ClutColumns : public Gtk::TreeModel::ColumnRecord class ClutColumns : public Gtk::TreeModel::ColumnRecord
{ {
public: public:
@@ -25,11 +29,24 @@ private:
ClutColumns(); ClutColumns();
}; };
int parseDir (const Glib::ustring& path); class ClutModel {
Gtk::TreeIter findRowByClutFilename( Gtk::TreeModel::Children childs, Glib::ustring filename ); public:
Glib::RefPtr<Gtk::TreeStore> m_model; Glib::RefPtr<Gtk::TreeStore> m_model;
ClutColumns m_columns; ClutColumns m_columns;
int count;
ClutModel(const Glib::ustring &path);
int parseDir (const Glib::ustring& path);
};
Glib::RefPtr<Gtk::TreeStore> &m_model();
ClutColumns &m_columns();
Gtk::TreeIter findRowByClutFilename( Gtk::TreeModel::Children childs, Glib::ustring filename );
static std::unique_ptr<ClutModel> cm; // we use a shared TreeModel for all the combo boxes, to save time (no need to reparse the clut dir multiple times)...
static std::unique_ptr<ClutModel> cm2; // ... except when options.multiDisplayMode (i.e. editors in their own window), where we need two. This is because we might have two combo boxes displayed at the same time in this case
int count; // the number of clut entries
bool batchMode;
}; };
class FilmSimulation : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel class FilmSimulation : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel