Explorar o código

refactor: update vector/0.4.1 matrix/0.2

Sam Jaffe hai 1 ano
pai
achega
6c6dceb5c1

+ 3 - 0
.gitmodules

@@ -17,3 +17,6 @@
 [submodule "external/stb"]
 	path = external/stb
 	url = https://github.com/nothings/stb.git
+[submodule "external/test-helpers"]
+	path = external/test-helpers
+	url = ssh://git@gogs.sjaffe.name:3000/sjjaffe/cpp-test-helpers.git

+ 56 - 0
engine/engine.xcodeproj/project.pbxproj

@@ -141,6 +141,27 @@
 			remoteGlobalIDString = CD3786171CF9F61100BE89B2;
 			remoteInfo = math;
 		};
+		CDAE63822B77D89D00551FB8 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = CDAE637C2B77D89D00551FB8 /* test-helpers.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = CD6030FC2AF67772000D9F31;
+			remoteInfo = "test-helpers";
+		};
+		CDAE63842B77D89D00551FB8 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = CDAE637C2B77D89D00551FB8 /* test-helpers.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = CDD965FA2B654D090091D92C;
+			remoteInfo = "test-helpers-test";
+		};
+		CDAE63862B77D8A700551FB8 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = CDAE637C2B77D89D00551FB8 /* test-helpers.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = CD6030FB2AF67772000D9F31;
+			remoteInfo = "test-helpers";
+		};
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
@@ -178,6 +199,7 @@
 		CD9F1BE22B74697A0035EDF5 /* graphics.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = graphics.xcodeproj; path = ../graphics/graphics.xcodeproj; sourceTree = "<group>"; };
 		CD9F1BEE2B74697A0035EDF5 /* math.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = math.xcodeproj; path = ../math/math.xcodeproj; sourceTree = "<group>"; };
 		CDA34D8422515C99008036A7 /* game */ = {isa = PBXFileReference; lastKnownFileType = folder; name = game; path = include/game; sourceTree = "<group>"; };
+		CDAE637C2B77D89D00551FB8 /* test-helpers.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "test-helpers.xcodeproj"; path = "../external/test-helpers/test-helpers.xcodeproj"; sourceTree = "<group>"; };
 		CDB1F8AE1D7A30CD00700C6B /* libengine.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libengine.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 		CDB1F8C61D7A312B00700C6B /* game_dispatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = game_dispatch.cpp; sourceTree = "<group>"; };
 		CDB1F8CA1D7A319A00700C6B /* scene.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scene.cpp; sourceTree = "<group>"; };
@@ -331,12 +353,22 @@
 			path = test;
 			sourceTree = "<group>";
 		};
+		CDAE637D2B77D89D00551FB8 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				CDAE63832B77D89D00551FB8 /* libtest-helpers.a */,
+				CDAE63852B77D89D00551FB8 /* test-helpers-test.xctest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
 		CDB1F8A51D7A30CD00700C6B = {
 			isa = PBXGroup;
 			children = (
 				CD9F1BC42B7469130035EDF5 /* gameutils.xcodeproj */,
 				CD9F1BE22B74697A0035EDF5 /* graphics.xcodeproj */,
 				CD9F1BEE2B74697A0035EDF5 /* math.xcodeproj */,
+				CDAE637C2B77D89D00551FB8 /* test-helpers.xcodeproj */,
 				CD62FCB622904A7B00376440 /* GoogleMock.xcodeproj */,
 				CDA34D8422515C99008036A7 /* game */,
 				CD8FBC7F2B743A7D00CE38F1 /* include */,
@@ -396,6 +428,7 @@
 			buildRules = (
 			);
 			dependencies = (
+				CDAE63872B77D8A700551FB8 /* PBXTargetDependency */,
 				CD62FCD522904A9700376440 /* PBXTargetDependency */,
 				CD62FCD022904A8900376440 /* PBXTargetDependency */,
 			);
@@ -472,6 +505,10 @@
 					ProductGroup = CD9F1BEF2B74697A0035EDF5 /* Products */;
 					ProjectRef = CD9F1BEE2B74697A0035EDF5 /* math.xcodeproj */;
 				},
+				{
+					ProductGroup = CDAE637D2B77D89D00551FB8 /* Products */;
+					ProjectRef = CDAE637C2B77D89D00551FB8 /* test-helpers.xcodeproj */;
+				},
 			);
 			projectRoot = "";
 			targets = (
@@ -552,6 +589,20 @@
 			remoteRef = CD9F1BF52B74697A0035EDF5 /* PBXContainerItemProxy */;
 			sourceTree = BUILT_PRODUCTS_DIR;
 		};
+		CDAE63832B77D89D00551FB8 /* libtest-helpers.a */ = {
+			isa = PBXReferenceProxy;
+			fileType = archive.ar;
+			path = "libtest-helpers.a";
+			remoteRef = CDAE63822B77D89D00551FB8 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		CDAE63852B77D89D00551FB8 /* test-helpers-test.xctest */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.cfbundle;
+			path = "test-helpers-test.xctest";
+			remoteRef = CDAE63842B77D89D00551FB8 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
 /* End PBXReferenceProxy section */
 
 /* Begin PBXResourcesBuildPhase section */
@@ -642,6 +693,11 @@
 			name = math;
 			targetProxy = CD9F1BF92B7469810035EDF5 /* PBXContainerItemProxy */;
 		};
+		CDAE63872B77D8A700551FB8 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = "test-helpers";
+			targetProxy = CDAE63862B77D8A700551FB8 /* PBXContainerItemProxy */;
+		};
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */

+ 2 - 2
engine/src/entity.cxx

@@ -34,8 +34,8 @@ void collidable::move(math::vec2 const & delta) {
 
 entity::entity(Json::Value const & json, graphics::object const & obj)
     : collidable(obj), velocity(to_vec2(json["velocity"])),
-      frame_texture_coords({make_vector(0.f, 0.f)}),
-      scale(json["size"].asFloat()), collides_with(0), collides_as(0) {
+      frame_texture_coords({{0.f, 0.f}}), scale(json["size"].asFloat()),
+      collides_with(0), collides_as(0) {
   render_info_.location.size *= scale;
   render_info_.frame.origin = frame_texture_coords[frame_index];
 }

+ 2 - 2
engine/src/fps_counter.cxx

@@ -41,6 +41,6 @@ std::string fps_counter::fps(env::clock::duration const & since) const {
 void fps_counter::set_frame_step(env::clock::duration const & since) {
   if (++counter_ != change_after_) { return; }
   counter_ = 0;
-  text_engine_->create_text_cells(
-      glyphs_, {make_vector(5.f, 780.f), make_vector(10.f, 20.f), fps(since)});
+  text_engine_->create_text_cells(glyphs_,
+                                  {{5.f, 780.f}, {10.f, 20.f}, fps(since)});
 }

+ 1 - 1
engine/src/game_dispatch.cpp

@@ -108,6 +108,6 @@ game_dispatch::make_renderer(math::vec2 const & bounds) const {
   math::vec2 const factor = screen_size_ / bounds;
   float const scale = std::min(factor[0], factor[1]);
   return std::make_shared<graphics::batch_renderer>(
-      renderer_.get(), math::matrix::scalar(make_vector(scale, scale, 1.f)));
+      renderer_.get(), math::matrix::scalar(math::vec3{scale, scale, 1.f}));
 }
 }

+ 3 - 3
engine/src/serial.cxx

@@ -26,11 +26,11 @@ Json::Value read_file(std::string const & abs_path) {
 }
 
 math::vec2 to_vec2(Json::Value const & json) {
-  return make_vector(json[0].asFloat(), json[1].asFloat());
+  return {json[0].asFloat(), json[1].asFloat()};
 }
 
 math::vec2i to_vec2i(Json::Value const & json) {
-  return make_vector(json[0].asInt(), json[1].asInt());
+  return {json[0].asInt(), json[1].asInt()};
 }
 
 math::vec2 to_vec2(Json::Value const & json, math::vec2 const & backup) {
@@ -58,7 +58,7 @@ identity<graphics::material> to_material(Json::Value const & json,
 graphics::object to_object(Json::Value const & json,
                            graphics::manager const & mgr) {
   identity<graphics::material> mat = to_material(json["material"], mgr);
-  auto frame_size = to_vec2(json["frameSize"], make_vector(1.f, 1.f));
+  auto frame_size = to_vec2(json["frameSize"], {1.f, 1.f});
   auto origin = to_vec2(json["position"]);
   return mgr.create_object(mat, origin, frame_size, json["scale"].asFloat());
   //    math::dim2::rectangle pos = {to_vec2(json["position"]),

+ 3 - 3
engine/src/text_engine.cxx

@@ -35,7 +35,7 @@ text_engine::text_engine(std::string const & font,
       glyphs_() {
   Json::Value value = get_font_config(font);
   math::vec2i const cells = to_vec2i(value["cells"]);
-  math::vec2 const cell_size = make_vector(1.f, 1.f) / cells;
+  math::vec2 const cell_size = math::vec2{1.f, 1.f} / cells;
   math::vec2 glyph_size = to_vec2(value["glyph_size"]);
   glyph_size /= std::max(glyph_size[0], glyph_size[1]);
   prototype_.frame.size = cell_size * glyph_size;
@@ -43,7 +43,7 @@ text_engine::text_engine(std::string const & font,
   for (int i = 0; i < cells[0]; ++i) {
     for (int j = 0; j < cells[1]; ++j) {
       glyphs_.emplace(*value["glyphs"][i][j].asCString(),
-                      (make_vector(j, cells[1] - i - 1)) * cell_size);
+                      (math::vec2i(j, cells[1] - i - 1)) * cell_size);
     }
   }
 }
@@ -55,7 +55,7 @@ void text_engine::create_text_cells(std::vector<graphics::object> & out,
   if (old_size != new_size) { out.resize(new_size, prototype_); }
   for (std::size_t i = old_size; i < new_size; ++i) {
     auto & obj = out[i];
-    obj.location = {in.origin + make_vector(in.size[0] * i, 0.f), in.size};
+    obj.location = {in.origin + math::vec2(in.size[0] * i, 0.f), in.size};
     obj.points = obj.location;
   }
   for (std::size_t i = 0; i < new_size; ++i) {

+ 10 - 9
engine/test/entity_test.cxx

@@ -10,9 +10,10 @@
 
 #include <sstream>
 
-#include <gmock/gmock.h>
 #include <json/json.h>
 
+#include <testing/xcode_gtest_helper.h>
+
 #include "mock_renderer.h"
 
 using namespace engine;
@@ -41,7 +42,7 @@ inline Json::Value to_json(std::string const & str) {
 }
 
 TEST(CollidableTest, ConstructsUsingGraphics) {
-  math::dim2::rectangle bounds{make_vector(0.f, 0.f), make_vector(1.f, 1.f)};
+  math::dim2::rectangle bounds{{0.f, 0.f}, {1.f, 1.f}};
   graphics::object obj{bounds, bounds, cast<graphics::material>(1), bounds};
 
   collidable collide{obj};
@@ -56,7 +57,7 @@ std::string const data = R"(
 )";
 
 TEST(EntityTest, ConstructsFromJson) {
-  math::dim2::rectangle bounds{make_vector(0.f, 0.f), make_vector(1.f, 1.f)};
+  math::dim2::rectangle bounds{{0.f, 0.f}, {1.f, 1.f}};
   graphics::object obj{bounds, bounds, cast<graphics::material>(1), bounds};
 
   entity ent{to_json(data), obj};
@@ -64,37 +65,37 @@ TEST(EntityTest, ConstructsFromJson) {
 }
 
 TEST(EntityTest, SizeParamAltersLocation) {
-  math::dim2::rectangle bounds{make_vector(0.f, 0.f), make_vector(1.f, 1.f)};
+  math::dim2::rectangle bounds{{0.f, 0.f}, {1.f, 1.f}};
   graphics::object obj{bounds, bounds, cast<graphics::material>(1), bounds};
 
   Json::Value json = to_json(data);
   json["size"] = 2.f;
   entity ent{json, obj};
-  math::dim2::rectangle expected{make_vector(0.f, 0.f), make_vector(2.f, 2.f)};
+  math::dim2::rectangle expected{{0.f, 0.f}, {2.f, 2.f}};
   EXPECT_THAT(ent.render_info().location, Ne(obj.location));
   EXPECT_THAT(ent.render_info().location, Eq(expected));
 }
 
 TEST(EntityTest, MoveWillAdjustPointsAndBounds) {
-  math::dim2::rectangle bounds{make_vector(0.f, 0.f), make_vector(1.f, 1.f)};
+  math::dim2::rectangle bounds{{0.f, 0.f}, {1.f, 1.f}};
   graphics::object obj{bounds, bounds, cast<graphics::material>(1), bounds};
 
   entity ent{to_json(data), obj};
   ent.update(1.f);
 
-  math::dim2::rectangle expected{make_vector(1.f, 2.f), make_vector(1.f, 1.f)};
+  math::dim2::rectangle expected{{1.f, 2.f}, {1.f, 1.f}};
   EXPECT_THAT(ent.render_info().location, Eq(expected));
   EXPECT_THAT(ent.render_info().points, Eq(math::dim2::quad(expected)));
 }
 
 TEST(EntityTest, MoveIsAFunctionOfVelocity) {
-  math::dim2::rectangle bounds{make_vector(0.f, 0.f), make_vector(1.f, 1.f)};
+  math::dim2::rectangle bounds{{0.f, 0.f}, {1.f, 1.f}};
   graphics::object obj{bounds, bounds, cast<graphics::material>(1), bounds};
 
   entity ent{to_json(data), obj};
   ent.update(0.5f);
 
-  math::dim2::rectangle expected{make_vector(0.5f, 1.f), make_vector(1.f, 1.f)};
+  math::dim2::rectangle expected{{0.5f, 1.f}, {1.f, 1.f}};
   EXPECT_THAT(ent.render_info().location, Eq(expected));
   EXPECT_THAT(ent.render_info().points, Eq(math::dim2::quad(expected)));
 }

+ 1 - 1
engine/test/fps_counter_test.cxx

@@ -8,7 +8,7 @@
 
 #include "game/engine/fps_counter.hpp"
 
-#include <gmock/gmock.h>
+#include <testing/xcode_gtest_helper.h>
 
 #include "game/engine/text_engine.hpp"
 #include "mock_renderer.h"

+ 4 - 5
engine/test/game_dispatch_test.cxx

@@ -10,11 +10,10 @@
 
 #include <memory>
 
-#include <gmock/gmock.h>
-
 #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"
@@ -22,7 +21,7 @@
 
 struct mock_scene : engine::scene {
   mock_scene(std::shared_ptr<engine::game_dispatch> game)
-      : engine::scene("mock", make_vector(0.f, 0.f), 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));
@@ -138,11 +137,11 @@ TEST_F(MouseEventTest, CanPressAndRelease) {
 
 TEST_F(MouseEventTest, TranslatesFrameOfRef) {
   // Resize the scene (not a supported operation)
-  scene_.reset(new mock_scene(dispatch_, make_vector(10.f, 10.f)));
+  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;
-  auto const where = make_vector(5.f, 5.f);
+  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);
 }

+ 21 - 20
engine/test/scene_test.cxx

@@ -8,14 +8,15 @@
 
 #include "game/engine/scene.hpp"
 
-#include <gmock/gmock.h>
-
 #include <game/util/env.hpp>
+#include <testing/xcode_gtest_helper.h>
 
 #include "game/engine/entity.hpp"
 #include "game/engine/game_dispatch.hpp"
 #include "mock_renderer.h"
 
+using testing::Values;
+
 struct test_scene : engine::scene {
   using engine::scene::scene;
 
@@ -169,24 +170,24 @@ struct BoundsTest : SceneTest, testing::WithParamInterface<math::vec2> {};
 
 TEST_F(BoundsTest, BoundsCheckIsPointInScreenZone) {
   // Confirm that the size is as expected...
-  EXPECT_THAT(scene().size(), Eq(make_vector(1600.f, 900.f)));
+  EXPECT_THAT(scene().size(), Eq(math::vec2(1600.f, 900.f)));
 
   // Lower-Left Corner
-  EXPECT_FALSE(scene().in_bounds(make_vector(-1.f, 0.f)));
-  EXPECT_FALSE(scene().in_bounds(make_vector(0.f, -1.f)));
-  EXPECT_TRUE(scene().in_bounds(make_vector(0.f, 0.f)));
+  EXPECT_FALSE(scene().in_bounds(math::vec2(-1.f, 0.f)));
+  EXPECT_FALSE(scene().in_bounds(math::vec2(0.f, -1.f)));
+  EXPECT_TRUE(scene().in_bounds(math::vec2(0.f, 0.f)));
   // Lower-Right Corner
-  EXPECT_FALSE(scene().in_bounds(make_vector(1600.f, -1.f)));
-  EXPECT_FALSE(scene().in_bounds(make_vector(1601.f, 0.f)));
-  EXPECT_TRUE(scene().in_bounds(make_vector(1600.f, 0.f)));
+  EXPECT_FALSE(scene().in_bounds(math::vec2(1600.f, -1.f)));
+  EXPECT_FALSE(scene().in_bounds(math::vec2(1601.f, 0.f)));
+  EXPECT_TRUE(scene().in_bounds(math::vec2(1600.f, 0.f)));
   // Upper-Right Corner
-  EXPECT_FALSE(scene().in_bounds(make_vector(1601.f, 900.f)));
-  EXPECT_FALSE(scene().in_bounds(make_vector(1600.f, 901.f)));
-  EXPECT_TRUE(scene().in_bounds(make_vector(1600.f, 900.f)));
+  EXPECT_FALSE(scene().in_bounds(math::vec2(1601.f, 900.f)));
+  EXPECT_FALSE(scene().in_bounds(math::vec2(1600.f, 901.f)));
+  EXPECT_TRUE(scene().in_bounds(math::vec2(1600.f, 900.f)));
   // Upper-Left Corner
-  EXPECT_FALSE(scene().in_bounds(make_vector(0.f, 901.f)));
-  EXPECT_FALSE(scene().in_bounds(make_vector(-1.f, 900.f)));
-  EXPECT_TRUE(scene().in_bounds(make_vector(0.f, 900.f)));
+  EXPECT_FALSE(scene().in_bounds(math::vec2(0.f, 901.f)));
+  EXPECT_FALSE(scene().in_bounds(math::vec2(-1.f, 900.f)));
+  EXPECT_TRUE(scene().in_bounds(math::vec2(0.f, 900.f)));
 }
 
 TEST_P(BoundsTest, BoundsCheckOnCollidableIsAnyPointInBounds) {
@@ -196,8 +197,8 @@ TEST_P(BoundsTest, BoundsCheckOnCollidableIsAnyPointInBounds) {
   EXPECT_TRUE(scene().in_bounds(&collide));
 }
 
-INSTANTIATE_TEST_CASE_P(Collidable, BoundsTest,
-                        ::testing::Values(make_vector(-1.f, -1.f),
-                                          make_vector(1599.f, -1.f),
-                                          make_vector(1599.f, 899.f),
-                                          make_vector(-1.f, 899.f)));
+INSTANTIATE_TEST_SUITE_P(Collidable, BoundsTest,
+                         Values(math::vec2(-1.f, -1.f),
+                                math::vec2(1599.f, -1.f),
+                                math::vec2(1599.f, 899.f),
+                                math::vec2(-1.f, 899.f)));

+ 7 - 7
engine/test/serial_test.cxx

@@ -9,11 +9,11 @@
 
 #include <sstream>
 
-#include <gmock/gmock.h>
 #include <json/json.h>
 #include <json/reader.h>
 
 #include <game/graphics/object.hpp>
+#include <testing/xcode_gtest_helper.h>
 
 #include "mock_renderer.h"
 
@@ -103,12 +103,12 @@ TEST_F(ObjectSerialTest, UsesPositionFromJsonForLocation) {
   Json::Value json = to_json(object_data);
   {
     graphics::object const obj = engine::to_object(json, mgr);
-    EXPECT_THAT(obj.location.origin, Eq(make_vector(0.0f, 0.0f)));
+    EXPECT_THAT(obj.location.origin, Eq(math::vec2(0.0f, 0.0f)));
   }
   {
     json["position"][0] = 5.f;
     graphics::object const obj = engine::to_object(json, mgr);
-    EXPECT_THAT(obj.location.origin, Eq(make_vector(5.0f, 0.0f)));
+    EXPECT_THAT(obj.location.origin, Eq(math::vec2(5.0f, 0.0f)));
   }
 }
 
@@ -116,18 +116,18 @@ TEST_F(ObjectSerialTest, SizeIsTextureSizeTimesScale) {
   Json::Value json = to_json(object_data);
   {
     graphics::object const obj = engine::to_object(json, mgr);
-    EXPECT_THAT(obj.location.size, Eq(make_vector(1.0f, 1.0f)));
+    EXPECT_THAT(obj.location.size, Eq(math::vec2(1.0f, 1.0f)));
   }
   {
     json["scale"] = 0.5f;
     graphics::object const obj = engine::to_object(json, mgr);
-    EXPECT_THAT(obj.location.size, Eq(make_vector(0.5f, 0.5f)));
+    EXPECT_THAT(obj.location.size, Eq(math::vec2(0.5f, 0.5f)));
   }
 }
 
 TEST_F(ObjectSerialTest, DefaultFrameIsEntireTex) {
   graphics::object const obj = engine::to_object(to_json(object_data), mgr);
-  EXPECT_THAT(obj.frame.size, Eq(make_vector(1.f, 1.f)));
+  EXPECT_THAT(obj.frame.size, Eq(math::vec2(1.f, 1.f)));
 }
 
 TEST_F(ObjectSerialTest, OverridesFrameSize) {
@@ -135,5 +135,5 @@ TEST_F(ObjectSerialTest, OverridesFrameSize) {
   json["frameSize"][0] = 0.125f;
   json["frameSize"][1] = 0.125f;
   graphics::object const obj = engine::to_object(json, mgr);
-  EXPECT_THAT(obj.frame.size, Eq(make_vector(0.125f, 0.125f)));
+  EXPECT_THAT(obj.frame.size, Eq(math::vec2(0.125f, 0.125f)));
 }

+ 3 - 3
engine/test/text_engine_test.cxx

@@ -8,7 +8,7 @@
 
 #include "game/engine/text_engine.hpp"
 
-#include <gmock/gmock.h>
+#include <testing/xcode_gtest_helper.h>
 
 #include "mock_renderer.h"
 
@@ -51,8 +51,8 @@ struct CreateTextTest : TextEngineTest {
 
   std::vector<graphics::object> out;
   std::unique_ptr<engine::text_engine> engine;
-  engine::text_engine::cell const data{make_vector(0.f, 0.f),
-                                       make_vector(10.f, 20.f), "HELLO"};
+  engine::text_engine::cell const data{math::vec2(0.f, 0.f),
+                                       math::vec2(10.f, 20.f), "HELLO"};
 };
 
 void CreateTextTest::SetUp() {

+ 1 - 1
external/matrix

@@ -1 +1 @@
-Subproject commit a41327180c0e3aeffc40f2a8d969c42ff219f6af
+Subproject commit 57a4763a169236d583d6a84d44021eccfd5177de

+ 1 - 0
external/test-helpers

@@ -0,0 +1 @@
+Subproject commit 2860eea66cd30adf2550f47e710ef7ca443fda5a

+ 1 - 1
external/vector

@@ -1 +1 @@
-Subproject commit 232f64be05a0584b5888d60f5628254ff6bb5b80
+Subproject commit a918330ac9b4a9faf2e3da692474a92b8f193ed0

+ 1 - 1
graphics/src/manager.cxx

@@ -117,7 +117,7 @@ object manager::create_object(identity<material> fromMaterial,
                               float scale) const {
   math::dim2::rectangle bounds{atPosition, frameWidth * get(fromMaterial).size *
                                                (scale ? scale : 1.f)};
-  return {bounds, bounds, fromMaterial, {make_vector(0.f, 0.f), frameWidth}};
+  return {bounds, bounds, fromMaterial, {{0.f, 0.f}, frameWidth}};
 }
 
 material const & manager::get(identity<material> identity) const {

+ 73 - 4
math/math.xcodeproj/project.pbxproj

@@ -18,6 +18,34 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
+		CD165A022B810FE8004CA4FF /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = CD1659FC2B810FE8004CA4FF /* expect.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = CDD476BD29C5423B00BDB829;
+			remoteInfo = expect;
+		};
+		CD165A042B810FE8004CA4FF /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = CD1659FC2B810FE8004CA4FF /* expect.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = CDEC1E8A235248390091D9F2;
+			remoteInfo = "expect-test";
+		};
+		CD165A062B810FFB004CA4FF /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = CD1659FC2B810FE8004CA4FF /* expect.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = CDD476BC29C5423B00BDB829;
+			remoteInfo = expect;
+		};
+		CD165A082B810FFB004CA4FF /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = CDAE62272B77B86700551FB8 /* matrix.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = CDAE62382B77B88A00551FB8;
+			remoteInfo = matrix;
+		};
 		CD1FCFD3227E194D00F9BF93 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = CD3786101CF9F61100BE89B2 /* Project object */;
@@ -98,6 +126,7 @@
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
+		CD1659FC2B810FE8004CA4FF /* expect.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = expect.xcodeproj; path = ../external/expect/expect.xcodeproj; sourceTree = "<group>"; };
 		CD1FCFC8227E193000F9BF93 /* shape_test.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = shape_test.cxx; sourceTree = "<group>"; };
 		CD1FCFCD227E194D00F9BF93 /* math-test.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "math-test.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
 		CD1FCFD1227E194D00F9BF93 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -134,6 +163,15 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		CD1659FD2B810FE8004CA4FF /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				CD165A032B810FE8004CA4FF /* libexpect.a */,
+				CD165A052B810FE8004CA4FF /* expect-test.xctest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
 		CD1FCFCE227E194D00F9BF93 /* math-test */ = {
 			isa = PBXGroup;
 			children = (
@@ -163,6 +201,7 @@
 		CD37860F1CF9F61100BE89B2 = {
 			isa = PBXGroup;
 			children = (
+				CD1659FC2B810FE8004CA4FF /* expect.xcodeproj */,
 				CDAE62272B77B86700551FB8 /* matrix.xcodeproj */,
 				CDAE622E2B77B86D00551FB8 /* vector.xcodeproj */,
 				CD1FCFD9227E197800F9BF93 /* GoogleMock.xcodeproj */,
@@ -267,6 +306,8 @@
 			buildRules = (
 			);
 			dependencies = (
+				CD165A072B810FFB004CA4FF /* PBXTargetDependency */,
+				CD165A092B810FFB004CA4FF /* PBXTargetDependency */,
 				CDAE62E82B77BC2200551FB8 /* PBXTargetDependency */,
 			);
 			name = math;
@@ -305,6 +346,10 @@
 			productRefGroup = CD3786191CF9F61100BE89B2 /* Products */;
 			projectDirPath = "";
 			projectReferences = (
+				{
+					ProductGroup = CD1659FD2B810FE8004CA4FF /* Products */;
+					ProjectRef = CD1659FC2B810FE8004CA4FF /* expect.xcodeproj */;
+				},
 				{
 					ProductGroup = CD1FCFDA227E197800F9BF93 /* Products */;
 					ProjectRef = CD1FCFD9227E197800F9BF93 /* GoogleMock.xcodeproj */;
@@ -327,6 +372,20 @@
 /* End PBXProject section */
 
 /* Begin PBXReferenceProxy section */
+		CD165A032B810FE8004CA4FF /* libexpect.a */ = {
+			isa = PBXReferenceProxy;
+			fileType = archive.ar;
+			path = libexpect.a;
+			remoteRef = CD165A022B810FE8004CA4FF /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		CD165A052B810FE8004CA4FF /* expect-test.xctest */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.cfbundle;
+			path = "expect-test.xctest";
+			remoteRef = CD165A042B810FE8004CA4FF /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
 		CD1FCFE1227E197800F9BF93 /* GoogleMock.framework */ = {
 			isa = PBXReferenceProxy;
 			fileType = wrapper.framework;
@@ -439,6 +498,16 @@
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
+		CD165A072B810FFB004CA4FF /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = expect;
+			targetProxy = CD165A062B810FFB004CA4FF /* PBXContainerItemProxy */;
+		};
+		CD165A092B810FFB004CA4FF /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = matrix;
+			targetProxy = CD165A082B810FFB004CA4FF /* PBXContainerItemProxy */;
+		};
 		CD1FCFD4227E194D00F9BF93 /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = CD3786171CF9F61100BE89B2 /* math */;
@@ -463,7 +532,7 @@
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LANGUAGE_STANDARD = "c++17";
 				CLANG_ENABLE_OBJC_WEAK = YES;
 				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
@@ -488,7 +557,7 @@
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+				CLANG_CXX_LANGUAGE_STANDARD = "c++17";
 				CLANG_ENABLE_OBJC_WEAK = YES;
 				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
@@ -509,7 +578,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LANGUAGE_STANDARD = "c++17";
 				CLANG_CXX_LIBRARY = "libc++";
 				CLANG_ENABLE_MODULES = YES;
 				CLANG_ENABLE_OBJC_ARC = YES;
@@ -564,7 +633,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LANGUAGE_STANDARD = "c++17";
 				CLANG_CXX_LIBRARY = "libc++";
 				CLANG_ENABLE_MODULES = YES;
 				CLANG_ENABLE_OBJC_ARC = YES;

+ 43 - 0
util/gameutils.xcodeproj/project.pbxproj

@@ -14,6 +14,20 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
+		CD165A132B811044004CA4FF /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = CD165A0A2B811044004CA4FF /* math.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = CD3786181CF9F61100BE89B2;
+			remoteInfo = math;
+		};
+		CD165A152B811044004CA4FF /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = CD165A0A2B811044004CA4FF /* math.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = CD1FCFCD227E194D00F9BF93;
+			remoteInfo = "math-test";
+		};
 		CD62FCED22904AD500376440 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = CD62FCE622904AD500376440 /* GoogleMock.xcodeproj */;
@@ -108,6 +122,7 @@
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
+		CD165A0A2B811044004CA4FF /* math.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = math.xcodeproj; path = ../math/math.xcodeproj; sourceTree = "<group>"; };
 		CD3AC7081D2C0726002B4BB0 /* libgameutils.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libgameutils.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 		CD62FCE622904AD500376440 /* GoogleMock.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GoogleMock.xcodeproj; path = "../../gmock-xcode-master/GoogleMock.xcodeproj"; sourceTree = "<group>"; };
 		CD62FCFC2291951400376440 /* linux_env.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = linux_env.cxx; sourceTree = "<group>"; };
@@ -140,9 +155,19 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		CD165A0B2B811044004CA4FF /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				CD165A142B811044004CA4FF /* libmath.dylib */,
+				CD165A162B811044004CA4FF /* math-test.xctest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
 		CD3AC6FF1D2C0726002B4BB0 = {
 			isa = PBXGroup;
 			children = (
+				CD165A0A2B811044004CA4FF /* math.xcodeproj */,
 				CDAE63132B77C2E700551FB8 /* resource_factory.xcodeproj */,
 				CDAE62E92B77C05200551FB8 /* scope_guard.xcodeproj */,
 				CDAE62F72B77C05800551FB8 /* vector.xcodeproj */,
@@ -314,6 +339,10 @@
 					ProductGroup = CD62FCE722904AD500376440 /* Products */;
 					ProjectRef = CD62FCE622904AD500376440 /* GoogleMock.xcodeproj */;
 				},
+				{
+					ProductGroup = CD165A0B2B811044004CA4FF /* Products */;
+					ProjectRef = CD165A0A2B811044004CA4FF /* math.xcodeproj */;
+				},
 				{
 					ProductGroup = CDAE63142B77C2E700551FB8 /* Products */;
 					ProjectRef = CDAE63132B77C2E700551FB8 /* resource_factory.xcodeproj */;
@@ -335,6 +364,20 @@
 /* End PBXProject section */
 
 /* Begin PBXReferenceProxy section */
+		CD165A142B811044004CA4FF /* libmath.dylib */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.dylib";
+			path = libmath.dylib;
+			remoteRef = CD165A132B811044004CA4FF /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		CD165A162B811044004CA4FF /* math-test.xctest */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.cfbundle;
+			path = "math-test.xctest";
+			remoteRef = CD165A152B811044004CA4FF /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
 		CD62FCEE22904AD500376440 /* GoogleMock.framework */ = {
 			isa = PBXReferenceProxy;
 			fileType = wrapper.framework;

+ 2 - 2
util/src/osx_env.mm

@@ -20,8 +20,8 @@ NSString* translate(std::string const & str) {
 
 math::vec2i init_screen() {
   NSRect frame = [[NSView focusView] frame];
-  return make_vector(static_cast<int>(frame.size.width),
-                     static_cast<int>(frame.size.height));
+  return {static_cast<int>(frame.size.width),
+          static_cast<int>(frame.size.height)};
 }
 
 }