Skip to content

Commit

Permalink
fix #477 update files watcher.
Browse files Browse the repository at this point in the history
  • Loading branch information
Nelson-numerical-software committed Aug 2, 2021
1 parent c7e5eb7 commit c4a355a
Show file tree
Hide file tree
Showing 14 changed files with 194 additions and 90 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -10,6 +10,8 @@

- allows .m file empty to be called.

- [#477](http://github.com/Nelson-numerical-software/nelson/issues/477): update files watcher.

## Bug Fixes:

- [#480](http://github.com/Nelson-numerical-software/nelson/issues/480): publisher name updated for windows installer.
Expand Down
1 change: 1 addition & 0 deletions modules/interpreter/src/c/nlsInterpreter.vcxproj
Expand Up @@ -325,6 +325,7 @@
<ItemGroup>
<ClInclude Include="..\cpp\AsciiToDouble.hpp" />
<ClInclude Include="..\cpp\CallMexBuiltin.hpp" />
<ClInclude Include="..\cpp\UpdatePathListener.hpp" />
<ClInclude Include="..\grammar\NelSonParser.h" />
<ClInclude Include="..\grammar\NelsonParserHelpers.hpp" />
<ClInclude Include="..\include\ActionMenu.hpp" />
Expand Down
3 changes: 3 additions & 0 deletions modules/interpreter/src/c/nlsInterpreter.vcxproj.filters
Expand Up @@ -376,6 +376,9 @@
<ClInclude Include="..\include\FunctionsInMemory.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\cpp\UpdatePathListener.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\CMakeLists.txt" />
Expand Down
3 changes: 1 addition & 2 deletions modules/interpreter/src/cpp/Evaluator.cpp
Expand Up @@ -127,7 +127,7 @@ class endData
ArrayOf endArray;
int index = 0;
size_t count = 0;
endData(ArrayOf p, int ndx, size_t cnt) : endArray(p), index(ndx), count(cnt) { }
endData(ArrayOf p, int ndx, size_t cnt) : endArray(p), index(ndx), count(cnt) {}
~endData() = default;
;
};
Expand Down Expand Up @@ -4200,7 +4200,6 @@ Evaluator::evalCLI()
{
while (1) {
if (!bpActive) {
FileWatcherManager::getInstance()->update();
clearStacks();
}
std::wstring commandLine;
Expand Down
164 changes: 83 additions & 81 deletions modules/interpreter/src/cpp/FileWatcherManager.cpp
Expand Up @@ -28,82 +28,36 @@
#include "FileWatcherManager.hpp"
#include "PathFuncManager.hpp"
#include "characters_encoding.hpp"
#include "MxGetExtension.hpp"
#include "UpdatePathListener.hpp"
//=============================================================================
namespace Nelson {
//=============================================================================
class UpdatePathListener : public FW::FileWatchListener
{
public:
UpdatePathListener() = default;
void
handleFileAction(WatchID watchid, const FW::String& dir, const FW::String& filename,
FW::Action action) override
{
switch (action) {
case FW::Action::Add: {
boost::filesystem::path pf = boost::filesystem::path(filename);
std::wstring file_extension = pf.extension().generic_wstring();
if (file_extension == L".m" || file_extension == L"." + getMexExtension()) {
boost::filesystem::path parent_dir = boost::filesystem::path(dir);
PathFuncManager::getInstance()->rehash(parent_dir.generic_wstring());
/*
#ifdef _MSC_VER
printf("Added: %ls\n", filename.c_str());
#else
printf("Added: %s\n", filename.c_str());
#endif
*/
}
} break;
case FW::Action::Delete: {
boost::filesystem::path pf = boost::filesystem::path(filename);
std::wstring file_extension = pf.extension().generic_wstring();
if (file_extension == L".m" || file_extension == L"." + getMexExtension()) {
boost::filesystem::path parent_dir = boost::filesystem::path(dir);
PathFuncManager::getInstance()->rehash(parent_dir.generic_wstring());
/*
#ifdef _MSC_VER
printf("Delete: %ls\n", filename.c_str());
#else
printf("Delete: %s\n", filename.c_str());
#endif
*/
}
} break;
case FW::Action::Modified:
boost::filesystem::path pf = boost::filesystem::path(filename);
std::wstring file_extension = pf.extension().generic_wstring();
if (file_extension == L".m" || file_extension == L"." + getMexExtension()) {
/*
#ifdef _MSC_VER
printf("Modified: %ls\n", filename.c_str());
#else
printf("Modified: %s\n", filename.c_str());
#endif
*/
}
break;
}
}
};
//=============================================================================
FileWatcherManager* FileWatcherManager::m_pInstance = nullptr;
//=============================================================================
FileWatcherManager::FileWatcherManager()
static std::wstring
uniformizePath(const std::wstring& directory)
{
auto* tmp = new FW::FileWatcher();
fileWatcher = (void*)tmp;
std::wstring uniformPath = directory;
if ((directory.back() == L'/') || (directory.back() == L'\\')) {
uniformPath.pop_back();
}
boost::filesystem::path path(uniformPath);
path = boost::filesystem::absolute(path);
uniformPath = path.generic_wstring();
#ifdef _MSC_VER
uniformPath = uniformPath + L"\\";
#else
uniformPath = uniformPath + L"/";
#endif
return uniformPath;
}
//=============================================================================
void
FileWatcherManager::release()
FileWatcherManager::FileWatcherManager()
{
auto* ptr = static_cast<FW::FileWatcher*>(fileWatcher);
if (ptr != nullptr) {
delete ptr;
fileWatcher = nullptr;
}
UpdatePathListener* _fileListener = new UpdatePathListener();
fileListener = static_cast<void*>(_fileListener);
FW::FileWatcher* _fileWatcher = new FW::FileWatcher();
fileWatcher = static_cast<void*>(_fileWatcher);
}
//=============================================================================
FileWatcherManager*
Expand All @@ -118,28 +72,41 @@ FileWatcherManager::getInstance()
void
FileWatcherManager::addWatch(const std::wstring& directory)
{
auto* watcher = new UpdatePathListener();
WatchID id = -1;
try {
std::wstring uniformizedPath = uniformizePath(directory);
std::map<std::wstring, std::pair<long, int>>::iterator it = watchIDsMap.find(uniformizedPath);
if (it == watchIDsMap.end()) {
UpdatePathListener* _fileListener = static_cast<UpdatePathListener*>(fileListener);
WatchID id;
try {
#ifdef _MSC_VER
id = (static_cast<FW::FileWatcher*>(fileWatcher))->addWatch(directory, watcher);
id = (static_cast<FW::FileWatcher*>(fileWatcher))->addWatch(directory, _fileListener);
#else
id = ((FW::FileWatcher*)fileWatcher)->addWatch(wstring_to_utf8(directory), watcher);
id = ((FW::FileWatcher*)fileWatcher)
->addWatch(wstring_to_utf8(directory), _fileListener);
#endif
} catch (const FW::FWException&) {
} catch (const FW::FWException&) {
id = -1;
}
if (id != -1) {
watchIDsMap.emplace(uniformizedPath, std::make_pair(id, 1));
}
} else {
it->second.second++;
}
}
//=============================================================================
void
FileWatcherManager::removeWatch(const std::wstring& directory)
{
try {
#ifdef _MSC_VER
(static_cast<FW::FileWatcher*>(fileWatcher))->removeWatch(directory);
#else
((FW::FileWatcher*)fileWatcher)->removeWatch(wstring_to_utf8(directory));
#endif
} catch (const FW::FWException&) {
std::wstring uniformizedPath = uniformizePath(directory);
std::map<std::wstring, std::pair<long, int>>::iterator it = watchIDsMap.find(uniformizedPath);
if (it != watchIDsMap.end()) {
if (it->second.second == 1) {
((FW::FileWatcher*)fileWatcher)->removeWatch(it->second.first);
watchIDsMap.erase(it);
} else {
it->second.second--;
}
}
}
//=============================================================================
Expand All @@ -152,5 +119,40 @@ FileWatcherManager::update()
}
}
//=============================================================================
} // namespace Nelson
void
FileWatcherManager::release()
{
UpdatePathListener* _fileListener = static_cast<UpdatePathListener*>(fileListener);
if (_fileListener) {
delete _fileListener;
_fileListener = nullptr;
fileListener = nullptr;
}
FW::FileWatcher* _fileWatcher = static_cast<FW::FileWatcher*>(fileWatcher);
if (_fileWatcher != nullptr) {
delete _fileWatcher;
_fileWatcher = nullptr;
fileWatcher = nullptr;
}
pathsToRefresh.clear();
watchIDsMap.clear();
}
//=============================================================================
void
FileWatcherManager::addPathToRefreshList(const std::wstring& directory)
{
pathsToRefresh.push_back(directory);
}
//=============================================================================
wstringVector
FileWatcherManager::getPathToRefresh(bool withClear)
{
wstringVector paths = pathsToRefresh;
if (withClear) {
pathsToRefresh.clear();
}
return paths;
}
//=============================================================================
}
//=============================================================================
2 changes: 1 addition & 1 deletion modules/interpreter/src/cpp/MacroFunctionDef.cpp
Expand Up @@ -439,7 +439,7 @@ MacroFunctionDef::updateCode()
this->returnVals = macroFunctionDef->returnVals;
this->ptrAstCodeAsVector = macroFunctionDef->ptrAstCodeAsVector;
this->setName(macroFunctionDef->getName());
}
}
} else {
this->code = getParsedScriptBlock();
this->arguments.clear();
Expand Down
16 changes: 16 additions & 0 deletions modules/interpreter/src/cpp/PathFuncManager.cpp
Expand Up @@ -172,10 +172,21 @@ PathFuncManager::find(const std::string& name, FunctionDefPtr& ptr)
return false;
}
//=============================================================================
void
PathFuncManager::fileWatcherUpdate()
{
FileWatcherManager::getInstance()->update();
wstringVector paths = FileWatcherManager::getInstance()->getPathToRefresh(true);
for (auto p : paths) {
rehash(p);
}
}
//=============================================================================
bool
PathFuncManager::find(const std::wstring& functionName, FileFunction** ff)
{
bool res = false;
fileWatcherUpdate();
if (_currentPath != nullptr) {
res = _currentPath->findFuncName(functionName, ff);
if (res) {
Expand Down Expand Up @@ -204,6 +215,7 @@ PathFuncManager::find(const std::wstring& functionName, FileFunction** ff)
bool
PathFuncManager::find(const std::wstring& functionName, std::wstring& filename)
{
fileWatcherUpdate();
if (_currentPath != nullptr) {
if (_currentPath->findFuncName(functionName, filename)) {
return true;
Expand All @@ -228,6 +240,7 @@ bool
PathFuncManager::find(const std::wstring& functionName, wstringVector& filesname)
{
filesname.clear();
fileWatcherUpdate();
std::wstring filename;
if (_currentPath != nullptr) {
if (_currentPath->findFuncName(functionName, filename)) {
Expand Down Expand Up @@ -333,6 +346,9 @@ bool
PathFuncManager::setCurrentUserPath(const std::wstring& path)
{
if (_currentPath != nullptr) {
if (isSamePath(path, _currentPath->getPath())) {
return true;
}
delete _currentPath;
}
_currentPath = new PathFunc(path);
Expand Down
68 changes: 68 additions & 0 deletions modules/interpreter/src/cpp/UpdatePathListener.hpp
@@ -0,0 +1,68 @@
//=============================================================================
// Copyright (c) 2016-present Allan CORNET (Nelson)
//=============================================================================
// This file is part of the Nelson.
//=============================================================================
// LICENCE_BLOCK_BEGIN
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.
// LICENCE_BLOCK_END
//=============================================================================
#pragma once
//=============================================================================
#include <string>
#include <boost/filesystem.hpp>
#include <FileWatcher.h>
#include "FileWatcherManager.hpp"
#include "MxGetExtension.hpp"
//=============================================================================
class UpdatePathListener : public FW::FileWatchListener
{
private:
//=============================================================================
void
appendIfNelsonFile(const FW::String& dir, const FW::String& filename)
{
boost::filesystem::path pf = boost::filesystem::path(filename);
std::wstring file_extension = pf.extension().generic_wstring();
if (file_extension == L".m" || file_extension == L"." + Nelson::getMexExtension()) {
boost::filesystem::path parent_dir = boost::filesystem::path(dir);
Nelson::FileWatcherManager::getInstance()->addPathToRefreshList(
parent_dir.generic_wstring());
}
}
//=============================================================================
public:
UpdatePathListener() = default;
void
handleFileAction(WatchID watchid, const FW::String& dir, const FW::String& filename,
FW::Action action) override
{
switch (action) {
case FW::Action::Add: {
appendIfNelsonFile(dir, filename);
} break;
case FW::Action::Delete: {
appendIfNelsonFile(dir, filename);
} break;
case FW::Action::Modified: {
} break;
}
}
};
//=============================================================================

0 comments on commit c4a355a

Please sign in to comment.