Skip to content

Commit

Permalink
getBinds
Browse files Browse the repository at this point in the history
  • Loading branch information
mwestphal committed Nov 26, 2024
1 parent 7916905 commit 1866360
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 25 deletions.
1 change: 1 addition & 0 deletions library/private/interactor_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class interactor_impl : public interactor
interactor& removeBinding(const interaction_bind_t& bind) override;
std::vector<std::string> getBindGroups() const override;
std::vector<interaction_bind_t> getBindsForGroup(std::string group) const override;
std::vector<interaction_bind_t> getBinds() const override;
std::pair<std::string, std::string> getBindingDocumentation(
const interaction_bind_t& bind) const override;

Expand Down
21 changes: 20 additions & 1 deletion library/public/interactor.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ class F3D_EXPORT interactor
}

/**
* Remove binding corresponding to provided interaction and modifiers
* Remove binding corresponding to provided bind.
* Does not do anything if the provided bind does not exists.
*/
virtual interactor& removeBinding(const interaction_bind_t& bind) = 0;

Expand All @@ -185,9 +186,16 @@ class F3D_EXPORT interactor

/**
* Return a vector of bind for the specified group, in order of addition
*
* Geting binds for a group that does not exists will throw a does_not_exists_exception.
*/
virtual std::vector<interaction_bind_t> getBindsForGroup(std::string group) const = 0;

/**
* Return a vector of all binds, in order of addition
*/
virtual std::vector<interaction_bind_t> getBinds() const = 0;

/**
* Get a pair of string documenting a binding.
* The first string is the documentation of the binding,
Expand All @@ -197,6 +205,8 @@ class F3D_EXPORT interactor
* If a binding was not documented on addition, the provided strings will be empty.
* The possible string can depends on the bindings but boolean value are expected to be
* "ON", "OFF", "N/A" (for optional values).
*
* Geting documentation for a bind that does not exists will throw a does_not_exists_exception.
*/
virtual std::pair<std::string, std::string> getBindingDocumentation(
const interaction_bind_t& bind) const = 0;
Expand Down Expand Up @@ -260,6 +270,15 @@ class F3D_EXPORT interactor
explicit already_exists_exception(const std::string& what = "");
};

/**
* An exception that can be thrown by the interactor
* when looking for something that does not exists
*/
struct does_not_exists_exception : public exception
{
explicit does_not_exists_exception(const std::string& what = "");
};

/**
* An exception that can be thrown by interactor::triggerCommand
* when a command callback throw an exception
Expand Down
6 changes: 6 additions & 0 deletions library/src/interactor.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ interactor::already_exists_exception::already_exists_exception(const std::string
{
}

//----------------------------------------------------------------------------
interactor::does_not_exists_exception::does_not_exists_exception(const std::string& what)
: exception(what)
{
}

//----------------------------------------------------------------------------
interactor::command_runtime_exception::command_runtime_exception(const std::string& what)
: exception(what)
Expand Down
22 changes: 21 additions & 1 deletion library/src/interactor_impl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,21 @@ std::vector<interaction_bind_t> interactor_impl::getBindsForGroup(std::string gr
{
output.emplace_back(it->second);
}
if (output.size() == 0)
{
throw interactor_impl::does_not_exists_exception(std::string("Bind: There is no binds for ") + group + " group");
}
return output;
}

//----------------------------------------------------------------------------
std::vector<interaction_bind_t> interactor_impl::getBinds() const
{
std::vector<interaction_bind_t> output;
for (const auto& [bind, command] : this->Internals->Bindings)
{
output.emplace_back(bind);
}
return output;
}

Expand All @@ -965,7 +980,12 @@ std::pair<std::string, std::string> interactor_impl::getBindingDocumentation(
const interaction_bind_t& bind) const
{
std::vector<std::tuple<std::string, std::string, std::string>> doc;
auto docFunc = this->Internals->Bindings[bind].DocumentationCallback;
auto it = this->Internals->Bindings.find(bind);
if (it == this->Internals->Bindings.end())
{
throw interactor_impl::does_not_exists_exception(std::string("Bind: ") + bind.format() + " does not exists");
}
auto docFunc = it->second.DocumentationCallback;
return docFunc ? docFunc() : std::make_pair(std::string(), std::string());
}

Expand Down
19 changes: 8 additions & 11 deletions library/src/window_impl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -452,21 +452,18 @@ void window_impl::UpdateDynamicOptions()
{
std::stringstream cheatSheetStream;
cheatSheetStream << "\n";
for (const std::string& group : this->Internals->Interactor->getBindGroups())
for (const auto& bind : this->Internals->Interactor->getBinds())
{
for (const auto& bind : this->Internals->Interactor->getBindsForGroup(group))
auto [doc, val] = this->Internals->Interactor->getBindingDocumentation(bind);
if (!doc.empty())
{
auto [doc, val] = this->Internals->Interactor->getBindingDocumentation(bind);
if (!doc.empty())
// XXX: This formatting will be reworked during ImGUI work
cheatSheetStream << " " << bind.format() << ": " << doc;
if (!val.empty())
{
// XXX: This formatting will be reworked during ImGUI work
cheatSheetStream << " " << bind.format() << ": " << doc;
if (!val.empty())
{
cheatSheetStream << " [" << val << "]";
}
cheatSheetStream << "\n";
cheatSheetStream << " [" << val << "]";
}
cheatSheetStream << "\n";
}
}
renderer->ConfigureCheatSheet(cheatSheetStream.str());
Expand Down
39 changes: 27 additions & 12 deletions library/testing/TestSDKInteractorDocumentation.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using mod_t = f3d::interaction_bind_t::ModifierKeys;

constexpr int nGroup = 3;
constexpr int nBindingsCamera = 7;
constexpr int nBindsCamera = 7;
constexpr std::string_view initDoc = "Toggle Orthographic Projection";
constexpr std::string_view initVal = "N/A";

Expand All @@ -15,21 +15,28 @@ int TestSDKInteractorDocumentation(int argc, char* argv[])
f3d::engine eng = f3d::engine::create(true);
f3d::interactor& inter = eng.getInteractor();

// Avoid testing something that changes often
int nBinds = inter.getBinds().size();

PseudoUnitTest test;

{
// Test initial state
test("Initial group size", inter.getBindGroups().size() == nGroup);
test("Initial nBindings Camera", inter.getBindsForGroup("Camera").size() == nBindingsCamera);
test("Initial nBinds Camera", inter.getBindsForGroup("Camera").size() == nBindsCamera);
const auto& [doc, val] = inter.getBindingDocumentation({ mod_t::ANY, "5" });
test("Initial doc and val", doc == initDoc && val == initVal);
}

{
// Test invalid args
test("Initial invalid group", inter.getBindsForGroup("Invalid").size() == 0);
const auto& [doc, val] = inter.getBindingDocumentation({ mod_t::ANY, "Invalid" });
test("Initial invalid doc and val", doc == "" && val == "");
// check exceptions for invalid args
test.expect<f3d::interactor::does_not_exists_exception>("Initial invalid group", [&]() {
inter.getBindsForGroup("Invalid");
});

test.expect<f3d::interactor::does_not_exists_exception>("Initial invalid bind", [&]() {
inter.getBindingDocumentation({ mod_t::ANY, "Invalid" });
});
}

// Remove all bindings
Expand All @@ -44,9 +51,15 @@ int TestSDKInteractorDocumentation(int argc, char* argv[])
{
// Test empty state
test("Empty group size", inter.getBindGroups().size() == 0);
test("Empty nBindings Camera", inter.getBindsForGroup("Camera").size() == 0);
const auto& [doc, val] = inter.getBindingDocumentation({ mod_t::ANY, "5" });
test("Empty doc and val", doc == "" && val == "");
test("Empty binds size", inter.getBinds().size() == 0);
// check exceptions for invalid args
test.expect<f3d::interactor::does_not_exists_exception>("Empty group", [&]() {
inter.getBindsForGroup("Camera");
});

test.expect<f3d::interactor::does_not_exists_exception>("Empty bind", [&]() {
inter.getBindingDocumentation({ mod_t::ANY, "5" });
});
}

// Add a dummy binding
Expand All @@ -56,7 +69,8 @@ int TestSDKInteractorDocumentation(int argc, char* argv[])
{
// Test dummy binding
test("Dummy group size", inter.getBindGroups().size() == 1);
test("Dummy nBindings DummyGroup", inter.getBindsForGroup("DummyGroup").size() == 1);
test("Dummy binds size", inter.getBinds().size() == 1);
test("Dummy nBinds DummyGroup", inter.getBindsForGroup("DummyGroup").size() == 1);
const auto& [doc, val] = inter.getBindingDocumentation({ mod_t::ANY, "DummyBind" });
test("Dummy doc and val", doc == "DummyDoc" && val == "DummyVal");
}
Expand All @@ -67,8 +81,9 @@ int TestSDKInteractorDocumentation(int argc, char* argv[])
{
// Test initial state
test("Initial group size after init", inter.getBindGroups().size() == nGroup);
test("Initial nBindings Camera after init",
inter.getBindsForGroup("Camera").size() == nBindingsCamera);
test("Initial binds size", inter.getBinds().size() == nBinds);
test("Initial nBinds Camera after init",
inter.getBindsForGroup("Camera").size() == nBindsCamera);
const auto& [doc, val] = inter.getBindingDocumentation({ mod_t::ANY, "5" });
test("Initial doc and val after init", doc == initDoc && val == initVal);
}
Expand Down
1 change: 1 addition & 0 deletions python/F3DPythonBindings.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ PYBIND11_MODULE(pyf3d, module)
.def("remove_binding", &f3d::interactor::removeBinding, "Remove interaction commands")
.def("get_bind_groups", &f3d::interactor::getBindGroups)
.def("get_binds_for_group", &f3d::interactor::getBindsForGroup)
.def("get_binds", &f3d::interactor::getBinds)
.def("get_binding_documentation", &f3d::interactor::getBindingDocumentation);

// f3d::mesh_t
Expand Down
4 changes: 4 additions & 0 deletions python/testing/test_interactor.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def test_binding():
for bind in binds:
inter.remove_binding(bind)
assert len(inter.get_bind_groups()) == 0
assert len(inter.get_binds()) == 0

# Smoke test
inter.add_binding(
Expand Down Expand Up @@ -77,4 +78,7 @@ def test_binding():
"DummyGroup",
doc_fn,
)
assert len(inter.get_bind_groups()) == 1
assert len(inter.get_binds()) == 5

inter.init_bindings()

0 comments on commit 1866360

Please sign in to comment.