Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/orbweaver/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Feb 13, 2022
2 parents e525144 + b434f67 commit 7f086e9
Show file tree
Hide file tree
Showing 103 changed files with 532 additions and 510 deletions.
4 changes: 2 additions & 2 deletions include/itransformnode.h
Expand Up @@ -20,6 +20,6 @@ class IMatrixTransform: public ITransformNode
{
public:

/// Return a modifiable reference to a contained transformation matrix
virtual Matrix4& localToParent() = 0;
/// Set the value of the contained transformation matrix
virtual void setLocalToParent(const Matrix4& localToParent) = 0;
};
56 changes: 27 additions & 29 deletions libs/module/StaticModule.h
Expand Up @@ -3,22 +3,6 @@
#include <functional>
#include "imodule.h"

/**
* greebo: Use a StaticModule to define a static RegisterableModule,
* which enlists itself automatically during application startup.
*
* The template parameter must be a RegisterModule class and
* is automatically registered with the ModuleRegistry by
* the StaticModule constructor.
*
* Since immediate registering is not desired, the constructor
* adds the incoming modules to a static std::list
* for a later routine to add the modules to the registry.
*
* Note: does NOT hold actual shared_ptrs of the RegisterableModule.
*
* Usage: StaticModule<RegisterableModule> myStaticModule;
*/
namespace module
{

Expand All @@ -27,12 +11,12 @@ namespace internal

/**
* Static container holding the modules registered by
* the StaticModule<T> helper. They will be picked up
* and acquired by the ModuleRegistry.
* To support scenarios like the unit test runner (where the
* the StaticModuleRegistration<T> helper. They will be picked up
* and acquired by the ModuleRegistry.
* To support scenarios like the unit test runner (where the
* modules are repeatedly loaded, initialised and shut down
* again) the module list is not cleared after registration,
* such that another startup event will have the full set of
* such that another startup event will have the full set of
* modules properly registered.
*/
typedef std::function<RegisterableModulePtr()> ModuleCreationFunc;
Expand All @@ -52,20 +36,34 @@ class StaticModuleList :

}

template <class ModuleType>
class StaticModule
/**
* @brief Helper object to register a specific RegisterableModule subclass.
*
* This class is intended to be used statically in the .cpp file of a particular module's
* implementing class, to register the module implementation with the ModuleRegistry. Since
* immediate registering is not desired, the constructor adds the incoming modules to a static
* std::list for a later routine to add the modules to the registry.
*
* Note that this object does NOT hold any reference or pointer to the actual module instance. It
* registers the TYPE of module which will later be instantiated and owned by the ModuleRegistry.
*
* @tparam ModuleType
* A RegisterableModule class which is automatically registered with the ModuleRegistry by the
* StaticModuleRegistration constructor.
*/
template <class ModuleType> class StaticModuleRegistration
{
static_assert(std::is_base_of<RegisterableModule, ModuleType>::value, "ModuleType must be of type RegisterableModule");
static_assert(std::is_base_of<RegisterableModule, ModuleType>::value,
"ModuleType must be of type RegisterableModule");

public:
StaticModule()
StaticModuleRegistration()
{
// Add a creator to the list in the backend, it will be called by the registry later
internal::StaticModuleList::Add([]()->RegisterableModulePtr
{
return std::make_shared<ModuleType>();
});
}
internal::StaticModuleList::Add(
[]() -> RegisterableModulePtr { return std::make_shared<ModuleType>(); }
);
}
};

} // namespace module
Expand Down
136 changes: 62 additions & 74 deletions libs/registry/Widgets.h
Expand Up @@ -13,131 +13,119 @@
namespace registry
{

namespace detail
{

template <typename Value_T, typename Widget_T>
void setWidgetValueIfKeyExists(const std::string& key, Widget_T& widget)
{
if (GlobalRegistry().keyExists(key))
widget.SetValue(registry::getValue<Value_T>(key));
}

} // namespace detail

/**
* Various bind() overloads to let widgets export their values to the registry
* as soon as they fire their changes signal. The value
* will be initialised with the one currently present in the registry.
*
* Note: due to the use of lambdas it's not possible to disconnect
* the widget's after calling bind(). The widget will keep writing
* Note: due to the use of lambdas it's not possible to disconnect
* the widget's after calling bind(). The widget will keep writing
* its value to the registry, unless it's destroyed.
*/
inline void bindWidget(wxSpinCtrlDouble* spinCtrl, const std::string& key)
{
// Set initial value then connect to changed signal
if (GlobalRegistry().keyExists(key))
{
spinCtrl->SetValue(registry::getValue<double>(key));
}

spinCtrl->Bind(wxEVT_SPINCTRLDOUBLE, [=] (wxSpinDoubleEvent& ev)
{
registry::setValue(key, spinCtrl->GetValue());
ev.Skip();
});
detail::setWidgetValueIfKeyExists<double>(key, *spinCtrl);
spinCtrl->Bind(wxEVT_SPINCTRLDOUBLE, [=](wxSpinDoubleEvent& ev) {
registry::setValue(key, spinCtrl->GetValue());
ev.Skip();
});
}

inline void bindWidget(wxTextCtrl* text, const std::string& key)
{
// Set initial value then connect to changed signal
if (GlobalRegistry().keyExists(key))
{
text->SetValue(registry::getValue<std::string>(key));
}

text->Bind(wxEVT_TEXT, [=] (wxCommandEvent& ev)
{
registry::setValue(key, text->GetValue().ToStdString());
ev.Skip();
});
detail::setWidgetValueIfKeyExists<std::string>(key, *text);
text->Bind(wxEVT_TEXT, [=](wxCommandEvent& ev) {
registry::setValue(key, text->GetValue().ToStdString());
ev.Skip();
});
}

inline void bindWidget(wxCheckBox* checkbox, const std::string& key)
{
// Set initial value then connect to changed signal
if (GlobalRegistry().keyExists(key))
{
checkbox->SetValue(registry::getValue<bool>(key));
}

checkbox->Bind(wxEVT_CHECKBOX, [=] (wxCommandEvent& ev)
{
registry::setValue(key, checkbox->GetValue() ? "1" : "0");
ev.Skip();
});
detail::setWidgetValueIfKeyExists<bool>(key, *checkbox);
checkbox->Bind(wxEVT_CHECKBOX, [=](wxCommandEvent& ev) {
registry::setValue(key, checkbox->GetValue() ? "1" : "0");
ev.Skip();
});
}

inline void bindWidget(wxToggleButton* toggleButton, const std::string& key)
{
// Set initial value then connect to changed signal
if (GlobalRegistry().keyExists(key))
{
toggleButton->SetValue(registry::getValue<bool>(key));
}

toggleButton->Bind(wxEVT_TOGGLEBUTTON, [=](wxCommandEvent& ev)
{
registry::setValue(key, toggleButton->GetValue() ? "1" : "0");
ev.Skip();
});
detail::setWidgetValueIfKeyExists<bool>(key, *toggleButton);
toggleButton->Bind(wxEVT_TOGGLEBUTTON, [=](wxCommandEvent& ev) {
registry::setValue(key, toggleButton->GetValue() ? "1" : "0");
ev.Skip();
});
}

// ------------- Variants supporting registry::Buffer ---------------------

inline void bindWidgetToBufferedKey(wxCheckBox* checkbox, const std::string& key,
inline void bindWidgetToBufferedKey(wxCheckBox* checkbox, const std::string& key,
Buffer& buffer, sigc::signal<void>& resetSignal)
{
// Set initial value then connect to changed signal
checkbox->SetValue(registry::getValue<std::string>(key) == "1");

checkbox->Bind(wxEVT_CHECKBOX, [=, &buffer] (wxCommandEvent& ev)
{
buffer.set(key, checkbox->GetValue() ? "1" : "0");
{
buffer.set(key, checkbox->GetValue() ? "1" : "0");
ev.Skip();
});

resetSignal.connect([=, &buffer] { if (buffer.keyExists(key)) { checkbox->SetValue(registry::getValue<std::string>(key) == "1"); } });
}

inline void bindWidgetToBufferedKey(wxSlider* slider, const std::string& key,
inline void bindWidgetToBufferedKey(wxSlider* slider, const std::string& key,
Buffer& buffer, sigc::signal<void>& resetSignal, int factor)
{
// Set initial value then connect to changed signal
slider->SetValue(registry::getValue<float>(key) * factor);

slider->Bind(wxEVT_SCROLL_CHANGED, [=, &buffer] (wxScrollEvent& ev)
{
buffer.set(key, string::to_string(static_cast<float>(slider->GetValue()) / factor));
{
buffer.set(key, string::to_string(static_cast<float>(slider->GetValue()) / factor));
ev.Skip();
});
slider->Bind(wxEVT_SCROLL_THUMBTRACK, [=, &buffer] (wxScrollEvent& ev)
{
buffer.set(key, string::to_string(static_cast<float>(slider->GetValue()) / factor));
{
buffer.set(key, string::to_string(static_cast<float>(slider->GetValue()) / factor));
ev.Skip();
});

resetSignal.connect([=, &buffer]
{
if (buffer.keyExists(key))
{
slider->SetValue(registry::getValue<float>(key) * factor);
}
{
if (buffer.keyExists(key))
{
slider->SetValue(registry::getValue<float>(key) * factor);
}
});
}

inline void bindWidgetToBufferedKey(wxChoice* choice, const std::string& key,
inline void bindWidgetToBufferedKey(wxChoice* choice, const std::string& key,
Buffer& buffer, sigc::signal<void>& resetSignal, bool storeValueNotIndex)
{
// Set initial value then connect to changed signal
choice->Select(storeValueNotIndex ?
choice->Select(storeValueNotIndex ?
choice->FindString(registry::getValue<std::string>(key)):
registry::getValue<int>(key));

choice->Bind(wxEVT_CHOICE, [=, &buffer] (wxCommandEvent& ev)
{
{
if (storeValueNotIndex)
{
buffer.set(key, choice->GetStringSelection().ToStdString());
buffer.set(key, choice->GetStringSelection().ToStdString());
}
else
{
Expand All @@ -150,15 +138,15 @@ inline void bindWidgetToBufferedKey(wxChoice* choice, const std::string& key,
resetSignal.connect([=, &buffer]
{
if (buffer.keyExists(key))
{
choice->Select(storeValueNotIndex ?
{
choice->Select(storeValueNotIndex ?
choice->FindString(registry::getValue<std::string>(key)):
registry::getValue<int>(key));
}
});
}

inline void bindWidgetToBufferedKey(wxTextCtrl* entry, const std::string& key,
inline void bindWidgetToBufferedKey(wxTextCtrl* entry, const std::string& key,
Buffer& buffer, sigc::signal<void>& resetSignal)
{
// Set initial value then connect to changed signal
Expand All @@ -168,21 +156,21 @@ inline void bindWidgetToBufferedKey(wxTextCtrl* entry, const std::string& key,
}

entry->Bind(wxEVT_TEXT, [=, &buffer] (wxCommandEvent& ev)
{
{
buffer.set(key, entry->GetValue().ToStdString());
ev.Skip();
});

resetSignal.connect([=, &buffer]
{
if (buffer.keyExists(key))
{
{
entry->SetValue(registry::getValue<std::string>(key));
}
});
}

inline void bindWidgetToBufferedKey(wxSpinCtrl* spinCtrl, const std::string& key,
inline void bindWidgetToBufferedKey(wxSpinCtrl* spinCtrl, const std::string& key,
Buffer& buffer, sigc::signal<void>& resetSignal)
{
// Set initial value then connect to changed signal
Expand All @@ -191,7 +179,7 @@ inline void bindWidgetToBufferedKey(wxSpinCtrl* spinCtrl, const std::string& key
spinCtrl->SetValue(registry::getValue<int>(key));
}

spinCtrl->Bind(wxEVT_SPINCTRL, [=, &buffer] (wxSpinEvent& ev)
spinCtrl->Bind(wxEVT_SPINCTRL, [=, &buffer] (wxSpinEvent& ev)
{
buffer.set(key, string::to_string(spinCtrl->GetValue()));
ev.Skip();
Expand All @@ -200,13 +188,13 @@ inline void bindWidgetToBufferedKey(wxSpinCtrl* spinCtrl, const std::string& key
resetSignal.connect([=, &buffer]
{
if (buffer.keyExists(key))
{
{
spinCtrl->SetValue(registry::getValue<int>(key));
}
});
}

inline void bindWidgetToBufferedKey(wxSpinCtrlDouble* spinCtrl, const std::string& key,
inline void bindWidgetToBufferedKey(wxSpinCtrlDouble* spinCtrl, const std::string& key,
Buffer& buffer, sigc::signal<void>& resetSignal)
{
// Set initial value then connect to changed signal
Expand All @@ -215,7 +203,7 @@ inline void bindWidgetToBufferedKey(wxSpinCtrlDouble* spinCtrl, const std::strin
spinCtrl->SetValue(registry::getValue<double>(key));
}

spinCtrl->Bind(wxEVT_SPINCTRLDOUBLE, [=, &buffer] (wxSpinDoubleEvent& ev)
spinCtrl->Bind(wxEVT_SPINCTRLDOUBLE, [=, &buffer] (wxSpinDoubleEvent& ev)
{
buffer.set(key, string::to_string(spinCtrl->GetValue()));
ev.Skip();
Expand All @@ -224,7 +212,7 @@ inline void bindWidgetToBufferedKey(wxSpinCtrlDouble* spinCtrl, const std::strin
resetSignal.connect([=, &buffer]
{
if (buffer.keyExists(key))
{
{
spinCtrl->SetValue(registry::getValue<double>(key));
}
});
Expand Down
18 changes: 11 additions & 7 deletions libs/string/string.h
Expand Up @@ -8,16 +8,20 @@
namespace string
{

/// \brief Returns <0 if \p string is lexicographically less than \p other after converting both to lower-case.
/// Returns >0 if \p string is lexicographically greater than \p other after converting both to lower-case.
/// Returns 0 if \p string is lexicographically equal to \p other after converting both to lower-case.
/// O(n)
inline int icmp(const char* string, const char* other)
/**
* @brief Case-insensitive string comparison.
*
* Behaves like the standard strcmp() but ignores case.
*
* @return A negative integer if lhs is lexicographically less than rhs (ignoring case), 0 if both
* are equal, or a positive integer if lhs is greater than rhs.
*/
inline int icmp(const char* lhs, const char* rhs)
{
#ifdef WIN32
return _stricmp(string, other);
return _stricmp(lhs, rhs);
#else
return strcasecmp(string, other);
return strcasecmp(lhs, rhs);
#endif
}

Expand Down

0 comments on commit 7f086e9

Please sign in to comment.