Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

For issue #217. #229

Merged
merged 1 commit into from
Dec 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Build/xcode5/PlayRho.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@
4768D3FD1E414A0100574143 /* Vector2.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4768D3FA1E414A0100574143 /* Vector2.hpp */; };
4768D4001E54E7CC00574143 /* StepConf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4768D3FF1E54E7CB00574143 /* StepConf.cpp */; };
476E8ABE1FC8CD9F00705BB5 /* UnitVec2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 476E8ABD1FC8CD9F00705BB5 /* UnitVec2.cpp */; };
476E8AC31FCF926F00705BB5 /* FunctionalShapeVisitor.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 476E8AC11FCF926F00705BB5 /* FunctionalShapeVisitor.hpp */; };
476E8AC71FCFA0D400705BB5 /* FunctionalJointVisitor.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 476E8AC51FCFA0D400705BB5 /* FunctionalJointVisitor.hpp */; };
4775A9381E05B032001C2332 /* StepConf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4775A9371E05B032001C2332 /* StepConf.cpp */; };
47791F801F92DB0700E257AF /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 47791F7A1F92D78F00E257AF /* imgui_draw.cpp */; };
47791F811F92DB0D00E257AF /* imgui_impl_glfw_gl3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 47791F7C1F92D83500E257AF /* imgui_impl_glfw_gl3.cpp */; };
Expand Down Expand Up @@ -512,6 +514,8 @@
4768D3FA1E414A0100574143 /* Vector2.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Vector2.hpp; sourceTree = "<group>"; };
4768D3FF1E54E7CB00574143 /* StepConf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StepConf.cpp; sourceTree = "<group>"; };
476E8ABD1FC8CD9F00705BB5 /* UnitVec2.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnitVec2.cpp; sourceTree = "<group>"; };
476E8AC11FCF926F00705BB5 /* FunctionalShapeVisitor.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = FunctionalShapeVisitor.hpp; sourceTree = "<group>"; };
476E8AC51FCFA0D400705BB5 /* FunctionalJointVisitor.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = FunctionalJointVisitor.hpp; sourceTree = "<group>"; };
477329D61F9BEFA200C521B4 /* SolarSystem.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = SolarSystem.hpp; sourceTree = "<group>"; };
4775A9371E05B032001C2332 /* StepConf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StepConf.cpp; sourceTree = "<group>"; };
47791F761F901B8700E257AF /* iforce2d_Trajectories.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = iforce2d_Trajectories.hpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -940,6 +944,7 @@
80BB8938141C3E5900F1753A /* DiskShape.hpp */,
80BB8939141C3E5900F1753A /* EdgeShape.cpp */,
80BB893A141C3E5900F1753A /* EdgeShape.hpp */,
476E8AC11FCF926F00705BB5 /* FunctionalShapeVisitor.hpp */,
474AFBF61EB1B2CB002AA6C8 /* MultiShape.cpp */,
474AFBF71EB1B2CB002AA6C8 /* MultiShape.hpp */,
80BB893B141C3E5900F1753A /* PolygonShape.cpp */,
Expand Down Expand Up @@ -1070,6 +1075,7 @@
80BB8971141C3E5900F1753A /* FrictionJoint.hpp */,
4787D6C41F2EA1DB008C115E /* FrictionJointDef.cpp */,
4787D6C51F2EA1DB008C115E /* FrictionJointDef.hpp */,
476E8AC51FCFA0D400705BB5 /* FunctionalJointVisitor.hpp */,
80BB8972141C3E5900F1753A /* GearJoint.cpp */,
80BB8973141C3E5900F1753A /* GearJoint.hpp */,
4787D6C81F2EA3A1008C115E /* GearJointDef.cpp */,
Expand Down Expand Up @@ -1275,6 +1281,7 @@
buildActionMask = 2147483647;
files = (
4726DD1F1D305E5D0012A882 /* ContactFeature.hpp in Headers */,
476E8AC71FCFA0D400705BB5 /* FunctionalJointVisitor.hpp in Headers */,
80BB8987141C3E5900F1753A /* PlayRho.hpp in Headers */,
47D28D9D1F6F28C70094C032 /* WrongState.hpp in Headers */,
4731DE581DEC908600E7F931 /* UnitVec2.hpp in Headers */,
Expand All @@ -1298,6 +1305,7 @@
4734B2211DC1340500F15E29 /* Span.hpp in Headers */,
80BB8998141C3E5900F1753A /* DiskShape.hpp in Headers */,
472724301E315E1A00C64921 /* Fixed.hpp in Headers */,
476E8AC31FCF926F00705BB5 /* FunctionalShapeVisitor.hpp in Headers */,
47C85D211F0DA14500F70C56 /* Templates.hpp in Headers */,
80BB899A141C3E5900F1753A /* EdgeShape.hpp in Headers */,
470F94CC1EC4D95D00AA3C82 /* BodyAtty.hpp in Headers */,
Expand Down
86 changes: 86 additions & 0 deletions PlayRho/Collision/Shapes/FunctionalShapeVisitor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2017 Louis Langholtz https://github.com/louis-langholtz/PlayRho
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/

#ifndef PLAYRHO_COLLISION_SHAPES_FUNCTIONALSHAPEVISITOR_HPP
#define PLAYRHO_COLLISION_SHAPES_FUNCTIONALSHAPEVISITOR_HPP

#include <PlayRho/Collision/Shapes/ShapeVisitor.hpp>
#include <functional>
#include <tuple>

namespace playrho {

/// @brief Functional shape visitor class.
/// @note This class is intended to provide an alternate interface for visiting shapes
/// via the use of lamdas instead of having to subclass <code>ShapeVisitor</code>.
/// @sa ShapeVisitor
class FunctionalShapeVisitor: public ShapeVisitor
{
public:
/// @brief Procedure alias.
template <class T>
using Proc = std::function<void(const T&)>;

/// @brief Tuple alias.
using Tuple = std::tuple<
Proc<DiskShape>,
Proc<EdgeShape>,
Proc<PolygonShape>,
Proc<ChainShape>,
Proc<MultiShape>
>;

Tuple procs; ///< Procedures.

/// @brief Uses given procedure.
/// @note Provide a builder pattern mutator method.
template <class T>
FunctionalShapeVisitor& Use(const Proc<T>& proc) noexcept
{
std::get<Proc<T>>(procs) = proc;
return *this;
}

// Overrides of all the base class's Visit methods...
// Uses decltype to ensure the correctly typed invocation of the Handle method.
void Visit(const DiskShape& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const EdgeShape& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const PolygonShape& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const ChainShape& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const MultiShape& arg) override { Handle<decltype(arg)>(arg); }

private:

/// @brief Handles the joint through the established function.
template <class T>
inline void Handle(T arg) const
{
const auto& proc = std::get<Proc<T>>(procs);
if (proc)
{
proc(arg);
}
}
};

} // namespace playrho

#endif // PLAYRHO_COLLISION_SHAPES_FUNCTIONALSHAPEVISITOR_HPP

123 changes: 123 additions & 0 deletions PlayRho/Dynamics/Joints/FunctionalJointVisitor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (c) 2017 Louis Langholtz https://github.com/louis-langholtz/PlayRho
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/

#ifndef PLAYRHO_DYNAMICS_JOINTS_FUNCTIONALJOINTVISITOR_HPP
#define PLAYRHO_DYNAMICS_JOINTS_FUNCTIONALJOINTVISITOR_HPP

#include <PlayRho/Dynamics/Joints/JointVisitor.hpp>
#include <functional>
#include <tuple>
#include <utility>

namespace playrho {

/// @brief Functional joint visitor class.
/// @note This class is intended to provide an alternate interface for visiting joints
/// via the use of lamdas instead of having to subclass <code>JointVisitor</code>.
class FunctionalJointVisitor: public JointVisitor
{
public:
/// @brief Procedure alias.
template <class T>
using Proc = std::function<void(T)>;

//using Tuple = std::tuple<Proc<Types>...>;
//FunctionalJointVisitor(const Tuple& v): procs{v} {}

/// @brief Tuple alias.
using Tuple = std::tuple<
Proc<const RevoluteJoint&>,
Proc< RevoluteJoint&>,
Proc<const PrismaticJoint&>,
Proc< PrismaticJoint&>,
Proc<const DistanceJoint&>,
Proc< DistanceJoint&>,
Proc<const PulleyJoint&>,
Proc< PulleyJoint&>,
Proc<const MouseJoint&>,
Proc< MouseJoint&>,
Proc<const GearJoint&>,
Proc< GearJoint&>,
Proc<const WheelJoint&>,
Proc< WheelJoint&>,
Proc<const WeldJoint&>,
Proc< WeldJoint&>,
Proc<const FrictionJoint&>,
Proc< FrictionJoint&>,
Proc<const RopeJoint&>,
Proc< RopeJoint&>,
Proc<const MotorJoint&>,
Proc< MotorJoint&>
>;

Tuple procs; ///< Procedures.

/// @brief Uses given procedure.
/// @note Provide a builder pattern mutator method.
template <class T>
FunctionalJointVisitor& Use(const Proc<T>& proc) noexcept
{
std::get<Proc<T>>(procs) = proc;
return *this;
}

// Overrides of all the base class's Visit methods...
// Uses decltype to ensure the correctly typed invocation of the Handle method.
void Visit(const RevoluteJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(RevoluteJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const PrismaticJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(PrismaticJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const DistanceJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(DistanceJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const PulleyJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(PulleyJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const MouseJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(MouseJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const GearJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(GearJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const WheelJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(WheelJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const WeldJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(WeldJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const FrictionJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(FrictionJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const RopeJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(RopeJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(const MotorJoint& arg) override { Handle<decltype(arg)>(arg); }
void Visit(MotorJoint& arg) override { Handle<decltype(arg)>(arg); }

private:

/// @brief Handles the joint through the established function.
template <class T>
inline void Handle(T arg) const
{
const auto& proc = std::get<Proc<T>>(procs);
if (proc)
{
proc(arg);
}
}
};

} // namespace playrho

#endif // PLAYRHO_DYNAMICS_JOINTS_FUNCTIONALJOINTVISITOR_HPP

9 changes: 4 additions & 5 deletions Testbed/Framework/Test.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
#include <PlayRho/PlayRho.hpp>
#include <PlayRho/Collision/RayCastOutput.hpp>
#include <PlayRho/Collision/ShapeSeparation.hpp>
#include <PlayRho/Collision/Shapes/ShapeVisitor.hpp>
#include <PlayRho/Collision/Shapes/FunctionalShapeVisitor.hpp>
#include <PlayRho/Dynamics/Contacts/PositionSolverManifold.hpp>
#include <PlayRho/Dynamics/Joints/FunctionalJointVisitor.hpp>
#include <PlayRho/Common/Range.hpp>
#include "Drawer.hpp"
#include "UiState.hpp"
Expand Down Expand Up @@ -418,12 +419,10 @@ inline void ForAll(World& world, const std::function<void(T& e)>& action);
template <>
inline void ForAll(World& world, const std::function<void(RevoluteJoint& e)>& action)
{
auto visitor = FunctionalJointVisitor{}.Use(action);
const auto range = world.GetJoints();
std::for_each(std::begin(range), std::end(range), [&](Joint* j) {
if (GetType(*j) == JointType::Revolute)
{
action(*reinterpret_cast<RevoluteJoint*>(j));
}
j->Accept(visitor);
});
}

Expand Down