aboutsummaryrefslogtreecommitdiff
path: root/src/test/Profiling.cpp
blob: 992928888efdb85923877aa484593ff7a54f2e47 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "system/ParticleSystem.h"
#include "system/PhysicsSystem.h"
#include "system/RenderSystem.h"
#include <cmath>
#include <chrono>
#include <gtest/gtest.h>

#define private public
#define protected public

#include <crepe/ComponentManager.h>
#include <crepe/api/Event.h>
#include <crepe/api/EventManager.h>
#include <crepe/api/GameObject.h>
#include <crepe/api/Rigidbody.h>
#include <crepe/api/Script.h>
#include <crepe/api/Transform.h>
#include <crepe/system/CollisionSystem.h>
#include <crepe/system/ScriptSystem.h>
#include <crepe/types.h>
#include <crepe/util/Log.h>

using namespace std;
using namespace std::chrono_literals;
using namespace crepe;
using namespace testing;

class CollisionHandler : public Script {
public:
	int box_id;

	CollisionHandler(int box_id) {
		this->box_id = box_id;
	}

	bool on_collision(const CollisionEvent& ev) {
		// test load?
		return true;
	}

	void init() {
		subscribe<CollisionEvent>([this](const CollisionEvent& ev) -> bool {
			return this->on_collision(ev);
		});
	}
	void update() {
		// Retrieve component from the same GameObject this script is on
	}
};

class Profiling : public Test {
public:
	ComponentManager mgr;
	// Add system used for profling tests 
	CollisionSystem collision_sys{mgr};
	PhysicsSystem physics_sys{mgr};
	ParticleSystem particle_sys{mgr};
	RenderSystem render_sys{mgr};
	ScriptSystem script_sys{mgr};

	// Store individual function timings
	std::map<std::string, long long> timings; 

	// Min and max gameobject that should and can be created
	int min_gameobject_count = 100;
	int max_gameobject_count = 100;
	
	void SetUp() override {
		
		GameObject do_not_use = mgr.new_object("DO_NOT_USE","",{0,0});
		do_not_use.add_component<Camera>(Color::WHITE);
		// initialize systems here:
		//calls init
		script_sys.update();
		//creates window
		render_sys.update();
	}

	// Helper function to time an update call and store its duration
	template <typename Func>
	long long time_function(const std::string& name, Func&& func) {
		auto start = std::chrono::steady_clock::now();
		func();
		auto end = std::chrono::steady_clock::now();
		auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
		timings[name] = duration; // Store the duration in microseconds
		return duration; // Return the duration in microseconds
	}

	// Run and profile all systems, return the total time in milliseconds
	long long run_all_systems() {
		long long total_microseconds = 0;
		total_microseconds += time_function("PhysicsSystem", [&]() { physics_sys.update(); });
		total_microseconds += time_function("CollisionSystem", [&]() { collision_sys.update(); });
		total_microseconds += time_function("ParticleSystem", [&]() { particle_sys.update(); });
		total_microseconds += time_function("RenderSystem", [&]() { render_sys.update(); });
		return total_microseconds;
	}

	// Print timings of all functions
	void log_timings(long long total_time,int game_object_count) const {
		std::stringstream ss;
		ss <<  std::endl <<"Function timings:\n";  // Starting with a header
		for (const auto& [name, duration] : timings) {
				ss << name << " took " << duration / 1000.0 << " ms (" << duration << " µs). " << std::endl;
		}
		ss << "Total time: " << total_time / 1000.0  << "ms (" << total_time  << " µs)" << std::endl;
		ss << "Amount of gameobjects: " << game_object_count << std::endl;
		// Use GTest INFO macro to print the accumulated log without extra newlines
		GTEST_LOG_(INFO) << ss.str();
	}
};

TEST_F(Profiling, Profiling_example) {
	int game_object_count = 0;
	long long total_time = 0;
	while (total_time < 16000) {
		game_object_count++;
		{
			//define gameobject used for testing
			GameObject gameobject = mgr.new_object("gameobject","",{0,0});
		}
		total_time = run_all_systems();
		if(game_object_count >= max_gameobject_count) break;
	}
	log_timings(total_time,game_object_count);
	EXPECT_GE(game_object_count, min_gameobject_count);
}