Moved the file modification checks in the library

This allows to transparently check the included files
This commit is contained in:
Paul Ferrand 2019-12-27 18:41:26 +01:00
parent 33d035804f
commit f02f96cad5
5 changed files with 53 additions and 23 deletions

View file

@ -132,7 +132,6 @@ typedef struct
sfizz_synth_t *synth;
bool expect_nominal_block_length;
char sfz_file_path[MAX_PATH_SIZE];
struct stat sfz_file_info;
int num_voices;
unsigned int preload_size;
sfizz_oversampling_factor_t oversampling;
@ -274,7 +273,6 @@ instantiate(const LV2_Descriptor *descriptor,
self->sample_rate = (float)rate;
self->expect_nominal_block_length = false;
self->sfz_file_path[0] = '\0';
self->sfz_file_info.st_mtime = (time_t)(-1);
self->num_voices = DEFAULT_VOICES;
self->oversampling = DEFAULT_OVERSAMPLING;
self->preload_size = DEFAULT_PRELOAD;
@ -524,25 +522,6 @@ sfizz_lv2_process_midi_event(sfizz_plugin_t *self, const LV2_Atom_Event *ev)
}
}
static bool
sfizz_lv2_check_modification(sfizz_plugin_t *self)
{
if (self->sfz_file_path == NULL)
return false;
if (strlen(self->sfz_file_path) == 0)
return false;
struct stat new_file_info;
if (stat(self->sfz_file_path, &new_file_info) != 0)
return false;
if (new_file_info.st_mtim.tv_sec > self->sfz_file_info.st_mtim.tv_sec)
return true;
return false;
}
static void
sfizz_lv2_status_log(sfizz_plugin_t *self)
{
@ -787,7 +766,6 @@ static void
sfizz_lv2_update_file_info(sfizz_plugin_t* self, const char* file_path)
{
strcpy(self->sfz_file_path, file_path);
stat(self->sfz_file_path, &self->sfz_file_info);
lv2_log_note(&self->logger, "[sfizz] File changed to: %s\n", self->sfz_file_path);
char *unknown_opcodes = sfizz_get_unknown_opcodes(self->synth);
@ -972,7 +950,7 @@ work(LV2_Handle instance,
}
else if (atom->type == self->sfizz_check_modification_uri)
{
if (sfizz_lv2_check_modification(self))
if (sfizz_should_reload_file(self->synth))
{
lv2_log_note(&self->logger, "[sfizz] File %s seems to have been updated, reloading.\n", self->sfz_file_path);
if (sfizz_load_file(self->synth, self->sfz_file_path))

View file

@ -344,6 +344,19 @@ void sfizz_disable_freewheeling(sfizz_synth_t* synth);
* @return char*
*/
char* sfizz_get_unknown_opcodes(sfizz_synth_t* synth);
/**
* @brief Check if the SFZ should be reloaded.
*
* Depending on the platform this can create file descriptors.
*
* @param synth
* @return true if any included files (including the root file) have
* been modified since the sfz file was loaded.
* @return false
*/
bool sfizz_should_reload_file(sfizz_synth_t* synth);
#ifdef __cplusplus
}
#endif

View file

@ -147,6 +147,7 @@ void sfz::Synth::clear()
masterOpcodes.clear();
groupOpcodes.clear();
unknownOpcodes.clear();
modificationTime = fs::file_time_type::min();
}
void sfz::Synth::handleGlobalOpcodes(const std::vector<Opcode>& members)
@ -289,6 +290,7 @@ bool sfz::Synth::loadSfzFile(const fs::path& filename)
DBG("Removed " << regions.size() - std::distance(regions.begin(), lastRegion) - 1 << " out of " << regions.size() << " regions.");
regions.resize(std::distance(regions.begin(), lastRegion) + 1);
modificationTime = checkModificationTime();
return parserReturned;
}
@ -633,3 +635,19 @@ void sfz::Synth::resetAllControllers(int delay) noexcept
region->registerCC(cc, 0);
}
}
fs::file_time_type sfz::Synth::checkModificationTime()
{
auto returnedTime = modificationTime;
for (auto file: getIncludedFiles()) {
const auto fileTime = fs::last_write_time(file);
if (returnedTime < fileTime)
returnedTime = fileTime;
}
return returnedTime;
}
bool sfz::Synth::shouldReloadFile()
{
return (checkModificationTime() > modificationTime);
}

View file

@ -342,6 +342,17 @@ public:
void disableFreeWheeling() noexcept;
const MidiState& getMidiState() const noexcept { return midiState; }
/**
* @brief Check if the SFZ should be reloaded.
*
* Depending on the platform this can create file descriptors.
*
* @return true if any included files (including the root file) have
* been modified since the sfz file was loaded.
* @return false
*/
bool shouldReloadFile();
protected:
/**
* @brief The parser callback; this is called by the parent object each time
@ -400,6 +411,8 @@ private:
*/
void buildRegion(const std::vector<Opcode>& regionOpcodes);
fs::file_time_type checkModificationTime();
// Opcode memory; these are used to build regions, as a new region
// will integrate opcodes from the group, master and global block
std::vector<Opcode> globalOpcodes;
@ -454,6 +467,8 @@ private:
int noteOffset { 0 };
int octaveOffset { 0 };
fs::file_time_type modificationTime { };
LEAK_DETECTOR(Synth);
};

View file

@ -239,6 +239,12 @@ char* sfizz_get_unknown_opcodes(sfizz_synth_t* synth)
return opcodeList;
}
bool sfizz_should_reload_file(sfizz_synth_t* synth)
{
auto self = reinterpret_cast<sfz::Synth*>(synth);
return self->shouldReloadFile();
}
#ifdef __cplusplus
}
#endif