| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- //
- // game_dispatch_test.cxx
- // engine-test
- //
- // Created by Sam Jaffe on 7/10/19.
- // Copyright © 2019 Sam Jaffe. All rights reserved.
- //
- #include "game/engine/game_dispatch.hpp"
- #include <memory>
- #include <game/graphics/renderer.hpp>
- #include <game/util/env.hpp>
- #include <math/vector/vector.hpp>
- #include <testing/xcode_gtest_helper.h>
- #include "game/engine/events.hpp"
- #include "game/engine/scene.hpp"
- #include "mock_renderer.h"
- struct mock_scene : engine::scene {
- mock_scene(std::shared_ptr<engine::game_dispatch> game)
- : engine::scene("mock", {0.f, 0.f}, game) {}
- mock_scene(std::shared_ptr<engine::game_dispatch> game, math::vec2 dim)
- : engine::scene("mock2", dim, game) {}
- MOCK_METHOD1(update, void(float));
- MOCK_METHOD0(render, void());
- MOCK_METHOD1(handle_key_event, void(engine::event::key_event));
- MOCK_METHOD1(handle_mouse_event, void(engine::event::mouse_event));
- };
- class GameDispatchTest : public testing::Test {
- protected:
- void SetUp() override;
- void TearDown() override;
- mock_scene & scene() const { return *scene_; }
- engine::game_dispatch & game() const { return *dispatch_; }
- std::shared_ptr<stub_renderer> renderer_;
- std::shared_ptr<engine::game_dispatch> dispatch_;
- std::shared_ptr<mock_scene> scene_;
- };
- void GameDispatchTest::SetUp() {
- env::resize_screen(math::vec2i{{100, 100}});
- renderer_.reset(new stub_renderer);
- dispatch_.reset(new engine::game_dispatch(renderer_));
- dispatch_->set_target_fps(env::fps::v60);
- scene_.reset(new mock_scene(dispatch_));
- game().register_scene(scene_);
- game().activate_scene("mock");
- }
- void GameDispatchTest::TearDown() {
- scene_.reset();
- dispatch_.reset();
- renderer_.reset();
- }
- using testing::_;
- using testing::AnyNumber;
- using testing::Eq;
- using testing::Field;
- using testing::FloatNear;
- using testing::Ge;
- using testing::Lt;
- using testing::Not;
- TEST_F(GameDispatchTest, ManagerIsFetchedFromRenderer) {
- EXPECT_THAT(&game().graphics_manager(), Eq(renderer_->manager().get()));
- }
- // TODO: Set FPS to a much smaller value for testing purposes (e.g. 512fps)
- TEST_F(GameDispatchTest, UpdateDispatchesToCurrentScene) {
- EXPECT_CALL(scene(), update(_)).Times(1);
- game().update();
- }
- TEST_F(GameDispatchTest, UpdateIsCappedInFrequencyByFPSParam) {
- auto fps60 = 1.0 / 60.0;
- EXPECT_CALL(scene(), update(Ge(fps60))).Times(AnyNumber());
- EXPECT_CALL(scene(), update(Lt(fps60))).Times(0);
- for (int i = 0; i < 10; i++) {
- game().update();
- }
- }
- TEST_F(GameDispatchTest, FPSCanBeChanged) {
- game().set_target_fps(env::fps::v120);
- auto fps120 = 1.0 / 120.0;
- EXPECT_CALL(scene(), update(Ge(fps120))).Times(AnyNumber());
- EXPECT_CALL(scene(), update(Lt(fps120))).Times(0);
- for (int i = 0; i < 10; i++) {
- game().update();
- }
- }
- TEST_F(GameDispatchTest, UpdateHasNoUpperBoundOnTime) {
- EXPECT_CALL(scene(), update(Ge(0.03))).Times(1);
- usleep(300000);
- game().update();
- }
- TEST_F(GameDispatchTest, SetCurrentTimestampOverridesWaiting) {
- auto fps60 = 1.0 / 60.0;
- EXPECT_CALL(scene(), update(Ge(0.03))).Times(0);
- EXPECT_CALL(scene(), update(FloatNear(fps60, 1E-2))).Times(1);
- usleep(300000);
- game().set_current_timestamp();
- game().update();
- }
- TEST_F(GameDispatchTest, RenderDispatchesToCurrentScene) {
- EXPECT_CALL(scene(), render()).Times(1);
- game().render();
- }
- using MouseEventTest = GameDispatchTest;
- TEST_F(MouseEventTest, DispatchesToCurrentScene) {
- EXPECT_CALL(scene(), handle_mouse_event(_)).Times(1);
- game().process_mouse_event({{0.f, 0.f}}, true);
- }
- MATCHER(WasPressed, "") {
- return (arg.type & engine::event::PRESSED_MASK) != 0;
- }
- TEST_F(MouseEventTest, CanPressAndRelease) {
- EXPECT_CALL(scene(), handle_mouse_event(WasPressed())).Times(1);
- game().process_mouse_event({}, true);
- EXPECT_CALL(scene(), handle_mouse_event(Not(WasPressed()))).Times(1);
- game().process_mouse_event({}, false);
- }
- TEST_F(MouseEventTest, TranslatesFrameOfRef) {
- // Resize the scene (not a supported operation)
- scene_.reset(new mock_scene(dispatch_, {10.f, 10.f}));
- game().register_scene(scene_);
- game().activate_scene("mock2");
- auto mouse_pos = &engine::event::mouse_event::current_mouse_position;
- math::vec2 const where{5.f, 5.f};
- EXPECT_CALL(scene(), handle_mouse_event(Field(mouse_pos, where))).Times(1);
- game().process_mouse_event({{50.f, 50.f}}, true);
- }
- using KeyEventTest = GameDispatchTest;
- TEST_F(KeyEventTest, DoesNotDispatchUnmappedKeys) {
- EXPECT_CALL(scene(), handle_key_event(_)).Times(0);
- game().process_key_event('A', true);
- }
- TEST_F(KeyEventTest, RemapsKeyWhenForwarding) {
- // TODO: Properly set this instead of using this garbage
- const_cast<engine::key_binding &>(scene().keys()).emplace('A', 'B');
- auto key_value = &engine::event::key_event::key;
- EXPECT_CALL(scene(), handle_key_event(Field(key_value, 'A'))).Times(0);
- EXPECT_CALL(scene(), handle_key_event(Field(key_value, 'B'))).Times(1);
- game().process_key_event('A', true);
- }
|