Skip to content
Snippets Groups Projects
Commit eaca323a authored by Sevinc Eroglu's avatar Sevinc Eroglu
Browse files

add sdl device and move eventdistributer implementation

#463
parent 2dcbc67f
No related branches found
No related tags found
1 merge request!156Feature/#463 mouse keyboard device
...@@ -20,6 +20,19 @@ ...@@ -20,6 +20,19 @@
// limitations under the License. // limitations under the License.
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#include <algorithm>
#include "phx/input/device.hpp" #include "phx/input/device.hpp"
namespace phx {} // namespace phx namespace phx {
void Device::EventDistributer::AddDevice(Device* device) {
devices_.push_back(device);
}
void Device::EventDistributer::RemoveDevice(Device* device) {
auto iterator =
std::remove_if(devices_.begin(), devices_.end(),
[device](Device* iteratee) { return device == iteratee; });
devices_.erase(iterator, devices_.end());
}
} // namespace phx
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#ifndef LIBRARY_PHX_INPUT_DEVICE_HPP_ #ifndef LIBRARY_PHX_INPUT_DEVICE_HPP_
#define LIBRARY_PHX_INPUT_DEVICE_HPP_ #define LIBRARY_PHX_INPUT_DEVICE_HPP_
#include <vector>
#include "phx/export.hpp" #include "phx/export.hpp"
namespace phx { namespace phx {
...@@ -31,6 +33,16 @@ class PHOENIX_EXPORT Device { ...@@ -31,6 +33,16 @@ class PHOENIX_EXPORT Device {
public: public:
virtual ~Device() = default; virtual ~Device() = default;
virtual void Update() = 0; virtual void Update() = 0;
class EventDistributer {
public:
virtual void Update() = 0;
void AddDevice(Device* device);
void RemoveDevice(Device* device);
protected:
std::vector<Device*> devices_;
};
}; };
} // namespace phx } // namespace phx
......
//------------------------------------------------------------------------------
// Project Phoenix
//
// Copyright (c) 2017-2018 RWTH Aachen University, Germany,
// Virtual Reality & Immersive Visualization Group.
//------------------------------------------------------------------------------
// License
//
// Licensed under the 3-Clause BSD License (the "License");
// you may not use this file except in compliance with the License.
// See the file LICENSE for the full text.
// You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//------------------------------------------------------------------------------
#include "phx/input/sdl_device.hpp"
#include "phx/core/logger.hpp"
namespace phx {
int SDLDevice::reference_counter_ = 0;
std::mutex SDLDevice::SDL_event_init_mutex_;
SDLDevice::SDLEventDistributer SDLDevice::SDL_event_distributer;
SDLDevice::SDLDevice() {
SDL_event_init_mutex_.lock();
if (reference_counter_ == 0) {
SDL_Init(SDL_INIT_EVENTS);
}
SDL_event_distributer.AddDevice(this);
reference_counter_++;
SDL_event_init_mutex_.unlock();
}
SDLDevice::~SDLDevice() {
SDL_event_init_mutex_.lock();
reference_counter_--;
if (reference_counter_ == 0) {
SDL_QuitSubSystem(SDL_INIT_EVENTS);
}
SDL_event_distributer.RemoveDevice(this);
SDL_event_init_mutex_.unlock();
}
void SDLDevice::Update() { SDL_event_distributer.Update(); }
void SDLDevice::SDLEventDistributer::Update() {
SDL_Event event;
while (SDL_PollEvent(&event) != 0) {
for (Device* device : devices_) {
dynamic_cast<SDLDevice*>(device)->OnSDLEvent(event);
}
}
}
} // namespace phx
//------------------------------------------------------------------------------
// Project Phoenix
//
// Copyright (c) 2017-2018 RWTH Aachen University, Germany,
// Virtual Reality & Immersive Visualization Group.
//------------------------------------------------------------------------------
// License
//
// Licensed under the 3-Clause BSD License (the "License");
// you may not use this file except in compliance with the License.
// See the file LICENSE for the full text.
// You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//------------------------------------------------------------------------------
#ifndef LIBRARY_PHX_INPUT_SDL_DEVICE_HPP_
#define LIBRARY_PHX_INPUT_SDL_DEVICE_HPP_
#include <mutex>
#include <vector>
#include "phx/input/device.hpp"
#include "phx/suppress_warnings.hpp"
SUPPRESS_WARNINGS_BEGIN
#include "SDL.h"
SUPPRESS_WARNINGS_END
#include "phx/export.hpp"
namespace phx {
class PHOENIX_EXPORT SDLDevice : public Device {
public:
SDLDevice();
virtual ~SDLDevice();
virtual void Update();
virtual void OnSDLEvent(const SDL_Event& event) = 0;
protected:
class SDLEventDistributer : public EventDistributer {
public:
void Update() override;
};
static SDLEventDistributer SDL_event_distributer;
private:
static int reference_counter_;
static std::mutex SDL_event_init_mutex_;
};
} // namespace phx
#endif // LIBRARY_PHX_INPUT_SDL_DEVICE_HPP_
...@@ -94,23 +94,11 @@ bool TrackedDevice::IsActive() const { ...@@ -94,23 +94,11 @@ bool TrackedDevice::IsActive() const {
return id_ != vr::k_unTrackedDeviceIndexInvalid; return id_ != vr::k_unTrackedDeviceIndexInvalid;
} }
void TrackedDevice::OpenVREventDistributer::AddDevice(TrackedDevice* device) {
tracked_devices_.push_back(device);
}
void TrackedDevice::OpenVREventDistributer::RemoveDevice(
TrackedDevice* device) {
auto iterator =
std::remove_if(tracked_devices_.begin(), tracked_devices_.end(),
[device](Device* iteratee) { return device == iteratee; });
tracked_devices_.erase(iterator, tracked_devices_.end());
}
void TrackedDevice::OpenVREventDistributer::Update() { void TrackedDevice::OpenVREventDistributer::Update() {
vr::VREvent_t event; vr::VREvent_t event;
while (vr::VRSystem()->PollNextEvent(&event, sizeof(event))) { while (vr::VRSystem()->PollNextEvent(&event, sizeof(event))) {
for (TrackedDevice* device : tracked_devices_) { for (Device* device : devices_) {
device->OnOpenVREvent(event); dynamic_cast<TrackedDevice*>(device)->OnOpenVREvent(event);
} }
} }
} }
......
...@@ -54,18 +54,13 @@ class PHOENIX_EXPORT TrackedDevice : public Device { ...@@ -54,18 +54,13 @@ class PHOENIX_EXPORT TrackedDevice : public Device {
virtual void OnOpenVREvent(const vr::VREvent_t& event) = 0; virtual void OnOpenVREvent(const vr::VREvent_t& event) = 0;
protected: protected:
class OpenVREventDistributer { class OpenVREventDistributer : public EventDistributer {
public: public:
void Update(); void Update() override;
void AddDevice(TrackedDevice* device);
void RemoveDevice(TrackedDevice* device);
private:
std::vector<TrackedDevice*> tracked_devices_;
}; };
static OpenVREventDistributer vr_event_distributer;
static vr::IVRSystem* vr_system_; static vr::IVRSystem* vr_system_;
static OpenVREventDistributer vr_event_distributer;
static std::vector<vr::TrackedDevicePose_t> last_wait_get_poses_; static std::vector<vr::TrackedDevicePose_t> last_wait_get_poses_;
glm::mat4 pose_; glm::mat4 pose_;
......
...@@ -174,7 +174,9 @@ add_test_cpplint(NAME "phoenix-tests--cpplint" ...@@ -174,7 +174,9 @@ add_test_cpplint(NAME "phoenix-tests--cpplint"
autoremove_mocked_test_source_from(${PHOENIX_TEST_SOURCES}) autoremove_mocked_test_source_from(${PHOENIX_TEST_SOURCES})
add_mocked_test(test_clear_pass LIBRARIES phoenix MOCKS opengl_mock) add_mocked_test(test_clear_pass LIBRARIES phoenix MOCKS opengl_mock)
add_mocked_test(test_input_system LIBRARIES phoenix MOCKS openvr_mock sdl_mock) add_mocked_test(test_SDL_device LIBRARIES phoenix MOCKS sdl_mock)
add_mocked_test(test_mouse LIBRARIES phoenix MOCKS sdl_mock)
add_mocked_test(test_keyboard LIBRARIES phoenix MOCKS sdl_mock)
add_mocked_test(test_geometry_pass LIBRARIES phoenix test_utilities MOCKS opengl_mock sdl_mock) add_mocked_test(test_geometry_pass LIBRARIES phoenix test_utilities MOCKS opengl_mock sdl_mock)
add_mocked_test(test_rendering_system LIBRARIES phoenix MOCKS opengl_mock sdl_mock) add_mocked_test(test_rendering_system LIBRARIES phoenix MOCKS opengl_mock sdl_mock)
add_mocked_test(test_shader LIBRARIES phoenix MOCKS opengl_mock) add_mocked_test(test_shader LIBRARIES phoenix MOCKS opengl_mock)
......
...@@ -25,15 +25,12 @@ ...@@ -25,15 +25,12 @@
#include "catch/catch.hpp" #include "catch/catch.hpp"
#include "phx/core/engine.hpp" #include "phx/core/engine.hpp"
#include "phx/input/input_system.hpp" #include "phx/input/sdl_device.hpp"
#include "trompeloeil.hpp" #include "trompeloeil.hpp"
#include "phx/suppress_warnings.hpp" #include "phx/suppress_warnings.hpp"
SUPPRESS_WARNINGS_BEGIN
#include "mocks/openvr_mock.hpp"
SUPPRESS_WARNINGS_END
#include "mocks/sdl_mock.hpp" #include "mocks/sdl_mock.hpp"
using trompeloeil::_; using trompeloeil::_;
...@@ -41,26 +38,30 @@ using trompeloeil::ne; ...@@ -41,26 +38,30 @@ using trompeloeil::ne;
extern template struct trompeloeil::reporter<trompeloeil::specialized>; extern template struct trompeloeil::reporter<trompeloeil::specialized>;
class SomeSDLDevice : public phx::SDLDevice {
MAKE_MOCK1(OnSDLEvent, void(const SDL_Event&));
};
SCENARIO("The input system captures low-level input events and forwards them.", SCENARIO("The input system captures low-level input events and forwards them.",
"[phx][phx::InputSystem]") { "[phx][phx::SDLDevice]") {
SDL_MOCK_ALLOW_ANY_CALL SDL_MOCK_ALLOW_ANY_CALL
OPENVR_MOCK_ALLOW_ANY_CALL
GIVEN("An engine with a DisplaySystem.") {
phx::Engine engine;
WHEN("I create an input system.") { WHEN("I create an SDL device.") {
THEN("SDL event subsystem is initialized.") { THEN("SDL event subsystem is initialized.") {
REQUIRE_CALL(sdl_mock.Get(), SDL_Init(SDL_INIT_EVENTS)).RETURN(0); REQUIRE_CALL(sdl_mock.Get(), SDL_Init(SDL_INIT_EVENTS)).RETURN(0);
engine.CreateSystem<phx::InputSystem>(); auto device = std::make_unique<SomeSDLDevice>();
}
}
GIVEN("An input system.") { WHEN("The SDL device is updated.") {
phx::InputSystem* input_system = engine.CreateSystem<phx::InputSystem>();
WHEN("The input system is updated.") {
THEN("SDL is requested to poll the pending events.") { THEN("SDL is requested to poll the pending events.") {
REQUIRE_CALL(sdl_mock.Get(), SDL_PollEvent(_)).RETURN(0); REQUIRE_CALL(sdl_mock.Get(), SDL_PollEvent(_)).RETURN(false);
input_system->Update(phx::FrameTimer::TimeInfo()); device->Update();
WHEN("The SDL device is destroyed.") {
THEN("SDL is requested to shutdown the event stuff.") {
REQUIRE_CALL(sdl_mock.Get(), SDL_QuitSubSystem(SDL_INIT_EVENTS));
device.reset();
}
}
} }
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment