diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index 94df97cb1..8cec10f6c 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -98,6 +98,10 @@ true + + false + true + true @@ -979,10 +983,11 @@ eepp-physics-debug ProjectExplorer.CustomExecutableRunConfiguration - false - 1 + true + 0 false - true + 1 + false false %{buildDir}../../../bin/ @@ -1146,10 +1151,10 @@ eepp-ui-perf-test-debug ProjectExplorer.CustomExecutableRunConfiguration - false - 1 + true + 0 false - 0 + 1 false false %{buildDir}../../../bin/ @@ -1167,7 +1172,7 @@ ecode-debug ProjectExplorer.CustomExecutableRunConfiguration - false + true --css=/root/.config/ecode/style.css 0 false diff --git a/projects/linux/ee.files b/projects/linux/ee.files index 509ccf92a..b18b64daf 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -1387,6 +1387,8 @@ ../../src/tools/ecode/plugins/lsp/lspdocumentclient.cpp ../../src/tools/ecode/plugins/lsp/lspdocumentclient.hpp ../../src/tools/ecode/plugins/lsp/lspprotocol.hpp +../../src/tools/ecode/plugins/plugin.cpp +../../src/tools/ecode/plugins/plugin.hpp ../../src/tools/ecode/plugins/pluginmanager.cpp ../../src/tools/ecode/plugins/pluginmanager.hpp ../../src/tools/ecode/plugins/xmltools/xmltoolsplugin.cpp diff --git a/src/eepp/ui/uinode.cpp b/src/eepp/ui/uinode.cpp index 3c1c61684..7e571eee1 100644 --- a/src/eepp/ui/uinode.cpp +++ b/src/eepp/ui/uinode.cpp @@ -1705,9 +1705,9 @@ Float UINode::convertLength( const CSS::StyleSheetLength& length, while ( NULL != node ) { if ( node->isWidget() ) { - std::string fontSizeStr( node->asType()->getPropertyString( + fontSizeStr = node->asType()->getPropertyString( CSS::StyleSheetSpecification::instance()->getProperty( - (Uint32)PropertyId::FontSize ) ) ); + (Uint32)PropertyId::FontSize ) ); if ( !fontSizeStr.empty() ) { Float num; if ( String::fromString( num, fontSizeStr ) ) { diff --git a/src/thirdparty/efsw b/src/thirdparty/efsw index aae269e0b..bc85bafae 160000 --- a/src/thirdparty/efsw +++ b/src/thirdparty/efsw @@ -1 +1 @@ -Subproject commit aae269e0be36292e4e5e1bb7f8672ca456fba956 +Subproject commit bc85bafae7d7b641e326ed5d01bfffd5eb0352f5 diff --git a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp index f416c375b..1d0fda44b 100644 --- a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp +++ b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.hpp @@ -2,6 +2,7 @@ #define ECODE_AUTOCOMPLETEPLUGIN_HPP #include "../lsp/lspprotocol.hpp" +#include "../plugin.hpp" #include "../pluginmanager.hpp" #include #include diff --git a/src/tools/ecode/plugins/formatter/formatterplugin.hpp b/src/tools/ecode/plugins/formatter/formatterplugin.hpp index 7cf917e4b..31224b064 100644 --- a/src/tools/ecode/plugins/formatter/formatterplugin.hpp +++ b/src/tools/ecode/plugins/formatter/formatterplugin.hpp @@ -1,6 +1,7 @@ #ifndef ECODE_FORMATTERPLUGIN_HPP #define ECODE_FORMATTERPLUGIN_HPP +#include "../plugin.hpp" #include "../pluginmanager.hpp" #include #include diff --git a/src/tools/ecode/plugins/linter/linterplugin.hpp b/src/tools/ecode/plugins/linter/linterplugin.hpp index 26b058b4e..89db45d7b 100644 --- a/src/tools/ecode/plugins/linter/linterplugin.hpp +++ b/src/tools/ecode/plugins/linter/linterplugin.hpp @@ -1,6 +1,7 @@ #ifndef ECODE_LINTERPLUGIN_HPP #define ECODE_LINTERPLUGIN_HPP +#include "../plugin.hpp" #include "../pluginmanager.hpp" #include #include diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.hpp b/src/tools/ecode/plugins/lsp/lspclientplugin.hpp index b7603e444..292e10b15 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.hpp @@ -1,6 +1,7 @@ #ifndef ECODE_LSPPLUGIN_HPP #define ECODE_LSPPLUGIN_HPP +#include "../plugin.hpp" #include "../pluginmanager.hpp" #include "lspclientservermanager.hpp" #include @@ -12,8 +13,6 @@ #include #include #include -#include -#include using namespace EE; using namespace EE::System; using namespace EE::UI; diff --git a/src/tools/ecode/plugins/plugin.cpp b/src/tools/ecode/plugins/plugin.cpp new file mode 100644 index 000000000..7fd3f1dfa --- /dev/null +++ b/src/tools/ecode/plugins/plugin.cpp @@ -0,0 +1,159 @@ +#include "plugin.hpp" +#include "pluginmanager.hpp" +#include + +namespace ecode { + +Plugin::Plugin( PluginManager* manager ) : + mManager( manager ), + mThreadPool( manager->getThreadPool() ), + mReady( false ), // All plugins will start as not ready until proved the contrary + mLoading( true ) // All plugins will start as loading until the load is complete, this is to + // avoid concurrency issues +{} + +bool Plugin::isReady() const { + return mReady; +} + +bool Plugin::isLoading() const { + return mLoading; +} + +bool Plugin::isShuttingDown() const { + return mShuttingDown; +} + +bool Plugin::hasFileConfig() { + return !mConfigPath.empty(); +} + +void Plugin::subscribeFileSystemListener() { + mConfigFileInfo = FileInfo( mConfigPath ); + mManager->subscribeFileSystemListener( this ); +} + +void Plugin::unsubscribeFileSystemListener() { + mManager->unsubscribeFileSystemListener( this ); +} + +std::string Plugin::getFileConfigPath() { + return mConfigPath; +} + +PluginManager* Plugin::getManager() const { + return mManager; +} + +void Plugin::onFileSystemEvent( const FileEvent& ev, const FileInfo& file ) { + if ( ev.type != FileSystemEventType::Modified || mShuttingDown || isLoading() ) + return; + + if ( file.getFilepath() != mConfigPath || + file.getModificationTime() == mConfigFileInfo.getModificationTime() ) + return; + + std::string fileContents; + FileSystem::fileGet( file.getFilepath(), fileContents ); + if ( getConfigFileHash() != String::hash( fileContents ) ) { + if ( mManager->isPluginReloadEnabled() && !isLoading() && isReady() ) { + mConfigFileInfo = file; + unsubscribeFileSystemListener(); + mManager->reload( getId() ); + } else { + Log::debug( "Plugin %s: Configuration file has been modified: %s. But " + "plugin reload is not enabled.", + getTitle().c_str(), mConfigPath.c_str() ); + } + } else { + Log::debug( "Plugin %s: Configuration file has been modified: %s. But contents " + "are the same.", + getTitle().c_str(), mConfigPath.c_str() ); + } +} + +void Plugin::setReady() { + if ( mReady ) { + Log::info( "Plugin: %s loaded and ready from process %u", getTitle().c_str(), + Sys::getProcessID() ); + } +} + +PluginBase::~PluginBase() { + mShuttingDown = true; + unsubscribeFileSystemListener(); + for ( auto editor : mEditors ) { + onBeforeUnregister( editor.first ); + for ( auto listener : editor.second ) + editor.first->removeEventListener( listener ); + editor.first->unregisterPlugin( this ); + } +} + +void PluginBase::onRegister( UICodeEditor* editor ) { + Lock l( mMutex ); + + std::vector listeners; + + listeners.push_back( + editor->addEventListener( Event::OnDocumentLoaded, [this, editor]( const Event* event ) { + Lock l( mMutex ); + const DocEvent* docEvent = static_cast( event ); + mDocs.insert( docEvent->getDoc() ); + mEditorDocs[editor] = docEvent->getDoc(); + onDocumentLoaded( docEvent->getDoc() ); + } ) ); + + listeners.push_back( + editor->addEventListener( Event::OnDocumentClosed, [this]( const Event* event ) { + { + Lock l( mMutex ); + const DocEvent* docEvent = static_cast( event ); + TextDocument* doc = docEvent->getDoc(); + onDocumentClosed( doc ); + onUnregisterDocument( doc ); + mDocs.erase( doc ); + } + } ) ); + + listeners.push_back( + editor->addEventListener( Event::OnDocumentChanged, [&, editor]( const Event* ) { + TextDocument* oldDoc = mEditorDocs[editor]; + TextDocument* newDoc = editor->getDocumentRef().get(); + Lock l( mMutex ); + mDocs.erase( oldDoc ); + mDocs.insert( newDoc ); + mEditorDocs[editor] = newDoc; + onDocumentChanged( editor, oldDoc ); + } ) ); + + onRegisterListeners( editor, listeners ); + + mEditors.insert( { editor, listeners } ); + if ( mDocs.count( editor->getDocumentRef().get() ) == 0 ) { + mDocs.insert( editor->getDocumentRef().get() ); + onRegisterDocument( editor->getDocumentRef().get() ); + } + mEditorDocs[editor] = editor->getDocumentRef().get(); +} + +void PluginBase::onUnregister( UICodeEditor* editor ) { + onBeforeUnregister( editor ); + if ( mShuttingDown ) + return; + Lock l( mMutex ); + TextDocument* doc = mEditorDocs[editor]; + auto cbs = mEditors[editor]; + for ( auto listener : cbs ) + editor->removeEventListener( listener ); + onUnregisterEditor( editor ); + mEditors.erase( editor ); + mEditorDocs.erase( editor ); + for ( auto editorIt : mEditorDocs ) + if ( editorIt.second == doc ) + return; + onUnregisterDocument( doc ); + mDocs.erase( doc ); +} + +} // namespace ecode diff --git a/src/tools/ecode/plugins/plugin.hpp b/src/tools/ecode/plugins/plugin.hpp new file mode 100644 index 000000000..bd37f48ce --- /dev/null +++ b/src/tools/ecode/plugins/plugin.hpp @@ -0,0 +1,99 @@ +#ifndef ECODE_PLUGIN_HPP +#define ECODE_PLUGIN_HPP + +#include +#include + +using namespace EE; +using namespace EE::UI; +using namespace EE::UI::Models; + +namespace ecode { + +class PluginManager; + +class Plugin : public UICodeEditorPlugin { + public: + explicit Plugin( PluginManager* manager ); + + void subscribeFileSystemListener(); + + void unsubscribeFileSystemListener(); + + bool isReady() const; + + bool isLoading() const; + + bool isShuttingDown() const; + + virtual bool hasFileConfig(); + + virtual std::string getFileConfigPath(); + + PluginManager* getManager() const; + + virtual String::HashType getConfigFileHash() { return 0; } + + virtual void onFileSystemEvent( const FileEvent& ev, const FileInfo& file ); + + protected: + PluginManager* mManager{ nullptr }; + std::shared_ptr mThreadPool; + std::string mConfigPath; + FileInfo mConfigFileInfo; + + std::atomic mReady{ false }; + std::atomic mLoading{ false }; + std::atomic mShuttingDown{ false }; + + void setReady(); +}; + +class PluginBase : public Plugin { + public: + explicit PluginBase( PluginManager* manager ) : Plugin( manager ) {} + + virtual ~PluginBase(); + + virtual void onRegister( UICodeEditor* ) override; + + virtual void onUnregister( UICodeEditor* ) override; + + virtual String::HashType getConfigFileHash() override { return mConfigHash; } + + protected: + //! Keep track of the registered editors + all the listeners registered to each editor + UnorderedMap> mEditors; + //! Keep track of the documents opened + UnorderedSet mDocs; + //! Documents and Editors mutex + Mutex mMutex; + //! Keep track of the document pointer of each editor + UnorderedMap mEditorDocs; + //! Keep track of the key bindings managed by the plugin + std::map mKeyBindings; /* cmd, shortcut */ + //! If the configuration is stored in a file, keep track of the config hash + String::HashType mConfigHash{ 0 }; + + virtual void onDocumentLoaded( TextDocument* ){}; + + virtual void onDocumentClosed( TextDocument* ){}; + + virtual void onDocumentChanged( UICodeEditor*, TextDocument* /*oldDoc*/ ){}; + + virtual void onRegisterListeners( UICodeEditor*, std::vector& /*listeners*/ ){}; + + //! Usually used to remove keybindings in an editor + virtual void onBeforeUnregister( UICodeEditor* ){}; + + virtual void onRegisterDocument( TextDocument* ){}; + + virtual void onUnregisterEditor( UICodeEditor* ){}; + + //! Usually used to unregister commands in a document + virtual void onUnregisterDocument( TextDocument* ){}; +}; + +} // namespace ecode + +#endif diff --git a/src/tools/ecode/plugins/pluginmanager.cpp b/src/tools/ecode/plugins/pluginmanager.cpp index 0750f6e63..4db78dfee 100644 --- a/src/tools/ecode/plugins/pluginmanager.cpp +++ b/src/tools/ecode/plugins/pluginmanager.cpp @@ -1,5 +1,6 @@ -#include "pluginmanager.hpp" #include "../filesystemlistener.hpp" +#include "plugin.hpp" +#include "pluginmanager.hpp" #include #include #include @@ -480,156 +481,4 @@ UIWindow* UIPluginManager::New( UISceneNode* sceneNode, PluginManager* manager, return win; } -Plugin::Plugin( PluginManager* manager ) : - mManager( manager ), - mThreadPool( manager->getThreadPool() ), - mReady( false ), // All plugins will start as not ready until proved the contrary - mLoading( true ) // All plugins will start as loading until the load is complete, this is to - // avoid concurrency issues -{} - -bool Plugin::isReady() const { - return mReady; -} - -bool Plugin::isLoading() const { - return mLoading; -} - -bool Plugin::isShuttingDown() const { - return mShuttingDown; -} - -bool Plugin::hasFileConfig() { - return !mConfigPath.empty(); -} - -void Plugin::subscribeFileSystemListener() { - mConfigFileInfo = FileInfo( mConfigPath ); - mManager->subscribeFileSystemListener( this ); -} - -void Plugin::unsubscribeFileSystemListener() { - mManager->unsubscribeFileSystemListener( this ); -} - -std::string Plugin::getFileConfigPath() { - return mConfigPath; -} - -PluginManager* Plugin::getManager() const { - return mManager; -} - -void Plugin::onFileSystemEvent( const FileEvent& ev, const FileInfo& file ) { - if ( ev.type != FileSystemEventType::Modified || mShuttingDown || isLoading() ) - return; - - if ( file.getFilepath() != mConfigPath || - file.getModificationTime() == mConfigFileInfo.getModificationTime() ) - return; - - std::string fileContents; - FileSystem::fileGet( file.getFilepath(), fileContents ); - if ( getConfigFileHash() != String::hash( fileContents ) ) { - if ( mManager->isPluginReloadEnabled() && !isLoading() && isReady() ) { - mConfigFileInfo = file; - unsubscribeFileSystemListener(); - mManager->reload( getId() ); - } else { - Log::debug( "Plugin %s: Configuration file has been modified: %s. But " - "plugin reload is not enabled.", - getTitle().c_str(), mConfigPath.c_str() ); - } - } else { - Log::debug( "Plugin %s: Configuration file has been modified: %s. But contents " - "are the same.", - getTitle().c_str(), mConfigPath.c_str() ); - } -} - -void Plugin::setReady() { - if ( mReady ) { - Log::info( "Plugin: %s loaded and ready from process %u", getTitle().c_str(), - Sys::getProcessID() ); - } -} - -PluginBase::~PluginBase() { - mShuttingDown = true; - unsubscribeFileSystemListener(); - for ( auto editor : mEditors ) { - onBeforeUnregister( editor.first ); - for ( auto listener : editor.second ) - editor.first->removeEventListener( listener ); - editor.first->unregisterPlugin( this ); - } -} - -void PluginBase::onRegister( UICodeEditor* editor ) { - Lock l( mMutex ); - - std::vector listeners; - - listeners.push_back( - editor->addEventListener( Event::OnDocumentLoaded, [this, editor]( const Event* event ) { - Lock l( mMutex ); - const DocEvent* docEvent = static_cast( event ); - mDocs.insert( docEvent->getDoc() ); - mEditorDocs[editor] = docEvent->getDoc(); - onDocumentLoaded( docEvent->getDoc() ); - } ) ); - - listeners.push_back( - editor->addEventListener( Event::OnDocumentClosed, [this]( const Event* event ) { - { - Lock l( mMutex ); - const DocEvent* docEvent = static_cast( event ); - TextDocument* doc = docEvent->getDoc(); - onDocumentClosed( doc ); - onUnregisterDocument( doc ); - mDocs.erase( doc ); - } - } ) ); - - listeners.push_back( - editor->addEventListener( Event::OnDocumentChanged, [&, editor]( const Event* ) { - TextDocument* oldDoc = mEditorDocs[editor]; - TextDocument* newDoc = editor->getDocumentRef().get(); - Lock l( mMutex ); - mDocs.erase( oldDoc ); - mDocs.insert( newDoc ); - mEditorDocs[editor] = newDoc; - onDocumentChanged( editor, oldDoc ); - } ) ); - - onRegisterListeners( editor, listeners ); - - mEditors.insert( { editor, listeners } ); - if ( mDocs.count( editor->getDocumentRef().get() ) == 0 ) { - mDocs.insert( editor->getDocumentRef().get() ); - onRegisterDocument( editor->getDocumentRef().get() ); - } - mEditorDocs[editor] = editor->getDocumentRef().get(); -} - -void PluginBase::onUnregister( UICodeEditor* editor ) { - onBeforeUnregister( editor ); - if ( mShuttingDown ) - return; - Lock l( mMutex ); - TextDocument* doc = mEditorDocs[editor]; - auto cbs = mEditors[editor]; - for ( auto listener : cbs ) - editor->removeEventListener( listener ); - onUnregisterEditor( editor ); - mEditors.erase( editor ); - mEditorDocs.erase( editor ); - for ( auto editorIt : mEditorDocs ) - if ( editorIt.second == doc ) - return; - onUnregisterDocument( doc ); - mDocs.erase( doc ); -} - } // namespace ecode diff --git a/src/tools/ecode/plugins/pluginmanager.hpp b/src/tools/ecode/plugins/pluginmanager.hpp index 69fb8cae5..0c06db679 100644 --- a/src/tools/ecode/plugins/pluginmanager.hpp +++ b/src/tools/ecode/plugins/pluginmanager.hpp @@ -407,88 +407,6 @@ class UIPluginManager { std::function loadFileCb ); }; -class Plugin : public UICodeEditorPlugin { - public: - explicit Plugin( PluginManager* manager ); - - void subscribeFileSystemListener(); - - void unsubscribeFileSystemListener(); - - bool isReady() const; - - bool isLoading() const; - - bool isShuttingDown() const; - - virtual bool hasFileConfig(); - - virtual std::string getFileConfigPath(); - - PluginManager* getManager() const; - - virtual String::HashType getConfigFileHash() { return 0; } - - virtual void onFileSystemEvent( const FileEvent& ev, const FileInfo& file ); - - protected: - PluginManager* mManager{ nullptr }; - std::shared_ptr mThreadPool; - std::string mConfigPath; - FileInfo mConfigFileInfo; - - std::atomic mReady{ false }; - std::atomic mLoading{ false }; - std::atomic mShuttingDown{ false }; - - void setReady(); -}; - -class PluginBase : public Plugin { - public: - explicit PluginBase( PluginManager* manager ) : Plugin( manager ) {} - - virtual ~PluginBase(); - - virtual void onRegister( UICodeEditor* ) override; - - virtual void onUnregister( UICodeEditor* ) override; - - virtual String::HashType getConfigFileHash() override { return mConfigHash; } - - protected: - //! Keep track of the registered editors + all the listeners registered to each editor - std::unordered_map> mEditors; - //! Keep track of the documents opened - std::set mDocs; - //! Documents and Editors mutex - Mutex mMutex; - //! Keep track of the document pointer of each editor - std::unordered_map mEditorDocs; - //! Keep track of the key bindings managed by the plugin - std::map mKeyBindings; /* cmd, shortcut */ - //! If the configuration is stored in a file, keep track of the config hash - String::HashType mConfigHash{ 0 }; - - virtual void onDocumentLoaded( TextDocument* ){}; - - virtual void onDocumentClosed( TextDocument* ){}; - - virtual void onDocumentChanged( UICodeEditor*, TextDocument* /*oldDoc*/ ){}; - - virtual void onRegisterListeners( UICodeEditor*, std::vector& /*listeners*/ ){}; - - //! Usually used to remove keybindings in an editor - virtual void onBeforeUnregister( UICodeEditor* ){}; - - virtual void onRegisterDocument( TextDocument* ){}; - - virtual void onUnregisterEditor( UICodeEditor* ){}; - - //! Usually used to unregister commands in a document - virtual void onUnregisterDocument( TextDocument* ){}; -}; - } // namespace ecode #endif // ECODE_PLUGINMANAGER_HPP diff --git a/src/tools/ecode/plugins/xmltools/xmltoolsplugin.hpp b/src/tools/ecode/plugins/xmltools/xmltoolsplugin.hpp index bf02daf6f..a4768ef12 100644 --- a/src/tools/ecode/plugins/xmltools/xmltoolsplugin.hpp +++ b/src/tools/ecode/plugins/xmltools/xmltoolsplugin.hpp @@ -1,12 +1,12 @@ #ifndef ECODE_XMLTOOLSPLUGIN_HPP #define ECODE_XMLTOOLSPLUGIN_HPP +#include "../plugin.hpp" #include "../pluginmanager.hpp" #include #include #include #include -#include using namespace EE; using namespace EE::System; using namespace EE::UI;