Skip to content

Commit aaf83d9

Browse files
Merge pull request #229 from louis-langholtz/helpers-20171129
For issue #217.
2 parents 51d0c7a + fabcc1c commit aaf83d9

File tree

4 files changed

+221
-5
lines changed

4 files changed

+221
-5
lines changed

Build/xcode5/PlayRho.xcodeproj/project.pbxproj

+8
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@
136136
4768D3FD1E414A0100574143 /* Vector2.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4768D3FA1E414A0100574143 /* Vector2.hpp */; };
137137
4768D4001E54E7CC00574143 /* StepConf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4768D3FF1E54E7CB00574143 /* StepConf.cpp */; };
138138
476E8ABE1FC8CD9F00705BB5 /* UnitVec2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 476E8ABD1FC8CD9F00705BB5 /* UnitVec2.cpp */; };
139+
476E8AC31FCF926F00705BB5 /* FunctionalShapeVisitor.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 476E8AC11FCF926F00705BB5 /* FunctionalShapeVisitor.hpp */; };
140+
476E8AC71FCFA0D400705BB5 /* FunctionalJointVisitor.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 476E8AC51FCFA0D400705BB5 /* FunctionalJointVisitor.hpp */; };
139141
4775A9381E05B032001C2332 /* StepConf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4775A9371E05B032001C2332 /* StepConf.cpp */; };
140142
47791F801F92DB0700E257AF /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 47791F7A1F92D78F00E257AF /* imgui_draw.cpp */; };
141143
47791F811F92DB0D00E257AF /* imgui_impl_glfw_gl3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 47791F7C1F92D83500E257AF /* imgui_impl_glfw_gl3.cpp */; };
@@ -512,6 +514,8 @@
512514
4768D3FA1E414A0100574143 /* Vector2.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Vector2.hpp; sourceTree = "<group>"; };
513515
4768D3FF1E54E7CB00574143 /* StepConf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StepConf.cpp; sourceTree = "<group>"; };
514516
476E8ABD1FC8CD9F00705BB5 /* UnitVec2.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnitVec2.cpp; sourceTree = "<group>"; };
517+
476E8AC11FCF926F00705BB5 /* FunctionalShapeVisitor.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = FunctionalShapeVisitor.hpp; sourceTree = "<group>"; };
518+
476E8AC51FCFA0D400705BB5 /* FunctionalJointVisitor.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = FunctionalJointVisitor.hpp; sourceTree = "<group>"; };
515519
477329D61F9BEFA200C521B4 /* SolarSystem.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = SolarSystem.hpp; sourceTree = "<group>"; };
516520
4775A9371E05B032001C2332 /* StepConf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StepConf.cpp; sourceTree = "<group>"; };
517521
47791F761F901B8700E257AF /* iforce2d_Trajectories.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = iforce2d_Trajectories.hpp; sourceTree = "<group>"; };
@@ -940,6 +944,7 @@
940944
80BB8938141C3E5900F1753A /* DiskShape.hpp */,
941945
80BB8939141C3E5900F1753A /* EdgeShape.cpp */,
942946
80BB893A141C3E5900F1753A /* EdgeShape.hpp */,
947+
476E8AC11FCF926F00705BB5 /* FunctionalShapeVisitor.hpp */,
943948
474AFBF61EB1B2CB002AA6C8 /* MultiShape.cpp */,
944949
474AFBF71EB1B2CB002AA6C8 /* MultiShape.hpp */,
945950
80BB893B141C3E5900F1753A /* PolygonShape.cpp */,
@@ -1070,6 +1075,7 @@
10701075
80BB8971141C3E5900F1753A /* FrictionJoint.hpp */,
10711076
4787D6C41F2EA1DB008C115E /* FrictionJointDef.cpp */,
10721077
4787D6C51F2EA1DB008C115E /* FrictionJointDef.hpp */,
1078+
476E8AC51FCFA0D400705BB5 /* FunctionalJointVisitor.hpp */,
10731079
80BB8972141C3E5900F1753A /* GearJoint.cpp */,
10741080
80BB8973141C3E5900F1753A /* GearJoint.hpp */,
10751081
4787D6C81F2EA3A1008C115E /* GearJointDef.cpp */,
@@ -1275,6 +1281,7 @@
12751281
buildActionMask = 2147483647;
12761282
files = (
12771283
4726DD1F1D305E5D0012A882 /* ContactFeature.hpp in Headers */,
1284+
476E8AC71FCFA0D400705BB5 /* FunctionalJointVisitor.hpp in Headers */,
12781285
80BB8987141C3E5900F1753A /* PlayRho.hpp in Headers */,
12791286
47D28D9D1F6F28C70094C032 /* WrongState.hpp in Headers */,
12801287
4731DE581DEC908600E7F931 /* UnitVec2.hpp in Headers */,
@@ -1298,6 +1305,7 @@
12981305
4734B2211DC1340500F15E29 /* Span.hpp in Headers */,
12991306
80BB8998141C3E5900F1753A /* DiskShape.hpp in Headers */,
13001307
472724301E315E1A00C64921 /* Fixed.hpp in Headers */,
1308+
476E8AC31FCF926F00705BB5 /* FunctionalShapeVisitor.hpp in Headers */,
13011309
47C85D211F0DA14500F70C56 /* Templates.hpp in Headers */,
13021310
80BB899A141C3E5900F1753A /* EdgeShape.hpp in Headers */,
13031311
470F94CC1EC4D95D00AA3C82 /* BodyAtty.hpp in Headers */,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright (c) 2017 Louis Langholtz https://github.com/louis-langholtz/PlayRho
3+
*
4+
* This software is provided 'as-is', without any express or implied
5+
* warranty. In no event will the authors be held liable for any damages
6+
* arising from the use of this software.
7+
*
8+
* Permission is granted to anyone to use this software for any purpose,
9+
* including commercial applications, and to alter it and redistribute it
10+
* freely, subject to the following restrictions:
11+
*
12+
* 1. The origin of this software must not be misrepresented; you must not
13+
* claim that you wrote the original software. If you use this software
14+
* in a product, an acknowledgment in the product documentation would be
15+
* appreciated but is not required.
16+
* 2. Altered source versions must be plainly marked as such, and must not be
17+
* misrepresented as being the original software.
18+
* 3. This notice may not be removed or altered from any source distribution.
19+
*/
20+
21+
#ifndef PLAYRHO_COLLISION_SHAPES_FUNCTIONALSHAPEVISITOR_HPP
22+
#define PLAYRHO_COLLISION_SHAPES_FUNCTIONALSHAPEVISITOR_HPP
23+
24+
#include <PlayRho/Collision/Shapes/ShapeVisitor.hpp>
25+
#include <functional>
26+
#include <tuple>
27+
28+
namespace playrho {
29+
30+
/// @brief Functional shape visitor class.
31+
/// @note This class is intended to provide an alternate interface for visiting shapes
32+
/// via the use of lamdas instead of having to subclass <code>ShapeVisitor</code>.
33+
/// @sa ShapeVisitor
34+
class FunctionalShapeVisitor: public ShapeVisitor
35+
{
36+
public:
37+
/// @brief Procedure alias.
38+
template <class T>
39+
using Proc = std::function<void(const T&)>;
40+
41+
/// @brief Tuple alias.
42+
using Tuple = std::tuple<
43+
Proc<DiskShape>,
44+
Proc<EdgeShape>,
45+
Proc<PolygonShape>,
46+
Proc<ChainShape>,
47+
Proc<MultiShape>
48+
>;
49+
50+
Tuple procs; ///< Procedures.
51+
52+
/// @brief Uses given procedure.
53+
/// @note Provide a builder pattern mutator method.
54+
template <class T>
55+
FunctionalShapeVisitor& Use(const Proc<T>& proc) noexcept
56+
{
57+
std::get<Proc<T>>(procs) = proc;
58+
return *this;
59+
}
60+
61+
// Overrides of all the base class's Visit methods...
62+
// Uses decltype to ensure the correctly typed invocation of the Handle method.
63+
void Visit(const DiskShape& arg) override { Handle<decltype(arg)>(arg); }
64+
void Visit(const EdgeShape& arg) override { Handle<decltype(arg)>(arg); }
65+
void Visit(const PolygonShape& arg) override { Handle<decltype(arg)>(arg); }
66+
void Visit(const ChainShape& arg) override { Handle<decltype(arg)>(arg); }
67+
void Visit(const MultiShape& arg) override { Handle<decltype(arg)>(arg); }
68+
69+
private:
70+
71+
/// @brief Handles the joint through the established function.
72+
template <class T>
73+
inline void Handle(T arg) const
74+
{
75+
const auto& proc = std::get<Proc<T>>(procs);
76+
if (proc)
77+
{
78+
proc(arg);
79+
}
80+
}
81+
};
82+
83+
} // namespace playrho
84+
85+
#endif // PLAYRHO_COLLISION_SHAPES_FUNCTIONALSHAPEVISITOR_HPP
86+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright (c) 2017 Louis Langholtz https://github.com/louis-langholtz/PlayRho
3+
*
4+
* This software is provided 'as-is', without any express or implied
5+
* warranty. In no event will the authors be held liable for any damages
6+
* arising from the use of this software.
7+
*
8+
* Permission is granted to anyone to use this software for any purpose,
9+
* including commercial applications, and to alter it and redistribute it
10+
* freely, subject to the following restrictions:
11+
*
12+
* 1. The origin of this software must not be misrepresented; you must not
13+
* claim that you wrote the original software. If you use this software
14+
* in a product, an acknowledgment in the product documentation would be
15+
* appreciated but is not required.
16+
* 2. Altered source versions must be plainly marked as such, and must not be
17+
* misrepresented as being the original software.
18+
* 3. This notice may not be removed or altered from any source distribution.
19+
*/
20+
21+
#ifndef PLAYRHO_DYNAMICS_JOINTS_FUNCTIONALJOINTVISITOR_HPP
22+
#define PLAYRHO_DYNAMICS_JOINTS_FUNCTIONALJOINTVISITOR_HPP
23+
24+
#include <PlayRho/Dynamics/Joints/JointVisitor.hpp>
25+
#include <functional>
26+
#include <tuple>
27+
#include <utility>
28+
29+
namespace playrho {
30+
31+
/// @brief Functional joint visitor class.
32+
/// @note This class is intended to provide an alternate interface for visiting joints
33+
/// via the use of lamdas instead of having to subclass <code>JointVisitor</code>.
34+
class FunctionalJointVisitor: public JointVisitor
35+
{
36+
public:
37+
/// @brief Procedure alias.
38+
template <class T>
39+
using Proc = std::function<void(T)>;
40+
41+
//using Tuple = std::tuple<Proc<Types>...>;
42+
//FunctionalJointVisitor(const Tuple& v): procs{v} {}
43+
44+
/// @brief Tuple alias.
45+
using Tuple = std::tuple<
46+
Proc<const RevoluteJoint&>,
47+
Proc< RevoluteJoint&>,
48+
Proc<const PrismaticJoint&>,
49+
Proc< PrismaticJoint&>,
50+
Proc<const DistanceJoint&>,
51+
Proc< DistanceJoint&>,
52+
Proc<const PulleyJoint&>,
53+
Proc< PulleyJoint&>,
54+
Proc<const MouseJoint&>,
55+
Proc< MouseJoint&>,
56+
Proc<const GearJoint&>,
57+
Proc< GearJoint&>,
58+
Proc<const WheelJoint&>,
59+
Proc< WheelJoint&>,
60+
Proc<const WeldJoint&>,
61+
Proc< WeldJoint&>,
62+
Proc<const FrictionJoint&>,
63+
Proc< FrictionJoint&>,
64+
Proc<const RopeJoint&>,
65+
Proc< RopeJoint&>,
66+
Proc<const MotorJoint&>,
67+
Proc< MotorJoint&>
68+
>;
69+
70+
Tuple procs; ///< Procedures.
71+
72+
/// @brief Uses given procedure.
73+
/// @note Provide a builder pattern mutator method.
74+
template <class T>
75+
FunctionalJointVisitor& Use(const Proc<T>& proc) noexcept
76+
{
77+
std::get<Proc<T>>(procs) = proc;
78+
return *this;
79+
}
80+
81+
// Overrides of all the base class's Visit methods...
82+
// Uses decltype to ensure the correctly typed invocation of the Handle method.
83+
void Visit(const RevoluteJoint& arg) override { Handle<decltype(arg)>(arg); }
84+
void Visit(RevoluteJoint& arg) override { Handle<decltype(arg)>(arg); }
85+
void Visit(const PrismaticJoint& arg) override { Handle<decltype(arg)>(arg); }
86+
void Visit(PrismaticJoint& arg) override { Handle<decltype(arg)>(arg); }
87+
void Visit(const DistanceJoint& arg) override { Handle<decltype(arg)>(arg); }
88+
void Visit(DistanceJoint& arg) override { Handle<decltype(arg)>(arg); }
89+
void Visit(const PulleyJoint& arg) override { Handle<decltype(arg)>(arg); }
90+
void Visit(PulleyJoint& arg) override { Handle<decltype(arg)>(arg); }
91+
void Visit(const MouseJoint& arg) override { Handle<decltype(arg)>(arg); }
92+
void Visit(MouseJoint& arg) override { Handle<decltype(arg)>(arg); }
93+
void Visit(const GearJoint& arg) override { Handle<decltype(arg)>(arg); }
94+
void Visit(GearJoint& arg) override { Handle<decltype(arg)>(arg); }
95+
void Visit(const WheelJoint& arg) override { Handle<decltype(arg)>(arg); }
96+
void Visit(WheelJoint& arg) override { Handle<decltype(arg)>(arg); }
97+
void Visit(const WeldJoint& arg) override { Handle<decltype(arg)>(arg); }
98+
void Visit(WeldJoint& arg) override { Handle<decltype(arg)>(arg); }
99+
void Visit(const FrictionJoint& arg) override { Handle<decltype(arg)>(arg); }
100+
void Visit(FrictionJoint& arg) override { Handle<decltype(arg)>(arg); }
101+
void Visit(const RopeJoint& arg) override { Handle<decltype(arg)>(arg); }
102+
void Visit(RopeJoint& arg) override { Handle<decltype(arg)>(arg); }
103+
void Visit(const MotorJoint& arg) override { Handle<decltype(arg)>(arg); }
104+
void Visit(MotorJoint& arg) override { Handle<decltype(arg)>(arg); }
105+
106+
private:
107+
108+
/// @brief Handles the joint through the established function.
109+
template <class T>
110+
inline void Handle(T arg) const
111+
{
112+
const auto& proc = std::get<Proc<T>>(procs);
113+
if (proc)
114+
{
115+
proc(arg);
116+
}
117+
}
118+
};
119+
120+
} // namespace playrho
121+
122+
#endif // PLAYRHO_DYNAMICS_JOINTS_FUNCTIONALJOINTVISITOR_HPP
123+

Testbed/Framework/Test.hpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323
#include <PlayRho/PlayRho.hpp>
2424
#include <PlayRho/Collision/RayCastOutput.hpp>
2525
#include <PlayRho/Collision/ShapeSeparation.hpp>
26-
#include <PlayRho/Collision/Shapes/ShapeVisitor.hpp>
26+
#include <PlayRho/Collision/Shapes/FunctionalShapeVisitor.hpp>
2727
#include <PlayRho/Dynamics/Contacts/PositionSolverManifold.hpp>
28+
#include <PlayRho/Dynamics/Joints/FunctionalJointVisitor.hpp>
2829
#include <PlayRho/Common/Range.hpp>
2930
#include "Drawer.hpp"
3031
#include "UiState.hpp"
@@ -418,12 +419,10 @@ inline void ForAll(World& world, const std::function<void(T& e)>& action);
418419
template <>
419420
inline void ForAll(World& world, const std::function<void(RevoluteJoint& e)>& action)
420421
{
422+
auto visitor = FunctionalJointVisitor{}.Use(action);
421423
const auto range = world.GetJoints();
422424
std::for_each(std::begin(range), std::end(range), [&](Joint* j) {
423-
if (GetType(*j) == JointType::Revolute)
424-
{
425-
action(*reinterpret_cast<RevoluteJoint*>(j));
426-
}
425+
j->Accept(visitor);
427426
});
428427
}
429428

0 commit comments

Comments
 (0)