This is for my university coursework.
I have a class called timestep that is going to be used as a typical timer in a game engine to calculate frame times, etc, and an application class.
I'm struggling to get my head around shared pointers, but am required to use one to access the timestep class from the application class. It doesn't throw up errors until the program is running, at which point it prints my "PRE TIMER" log to the console, and throws an exception after reaching timer->setStart(), flags the line start = ..... in the setStart method, and says **this** was nullptr.
Timestep.h:
#pragma once
#include <chrono>
namespace Engine {
class Timestep {
private:
std::chrono::high_resolution_clock::time_point start;
std::chrono::high_resolution_clock::time_point end;
public:
Timestep();
void setStart();
void setEnd();
float getTimeSeconds() const;
float GetTimeMilliSeconds() const;
};
}
timestep.cpp:
#pragma once
#include "engine_pch.h"
#include "core/timestep.h"
namespace Engine {
Timestep::Timestep(){}
void Timestep::setStart() {
start = std::chrono::high_resolution_clock::now();
}
void Timestep::setEnd() {
end = std::chrono::high_resolution_clock::now();
}
float Timestep::getTimeSeconds() const {
std::chrono::duration<float> time = end - start;
return time.count();
}
float Timestep::GetTimeMilliSeconds() const {
std::chrono::duration<float, std::milli> time = end - start;
return time.count();
}
}
application.cpp:
#include "engine_pch.h"
#include "core/application.h"
namespace Engine {
Application* Application::s_instance = nullptr;
std::shared_ptr<Timestep> timer;
Application::Application()
{
if (s_instance == nullptr)
{
s_instance = this;
}
log::log();
LOG_INFO("Logger init success");
}
Application::~Application()
{
}
void Application::run()
{
LOG_INFO("PRE TIMER");
timer->setStart();
LOG_INFO("POST TIMER");
while (s_instance) {
timer->setEnd();
float a = timer->getTimeSeconds();
LOG_INFO("Time since last frame is {0}", a);
timer->setStart();
}
}
}
Apparently, your timer in application.cpp is not pointing to any instance of Timestep, incurring the nullptr error. Explained simply, your shared pointer was not initialized.
Assuming that you want a separate instance of Timestep for each instance of Application, maybe you could solve the issue by initializing your std::shared_ptr<Timestep> timer;
Instead of
std::shared_ptr<Timestep> timer;
Try
std::shared_ptr<Timestep> timer(new Timestep());
Related
So this is the first time i've tried to do performance measuring and have followed some online resources to test a smaller version of my code before i try it on my coursework. Unfortunately i can't get it to print the time taken to complete the function and i'm not sure if i'm even doing it right.
#include <string>
#include <iostream>
#include <unordered_map>
#include <chrono>
using namespace std;
class Timer {
public:
Timer() {
startTimept = std::chrono::high_resolution_clock::now();
}
~Timer() {
Timer Stop();
}
void Stop() {
auto endTimept = std::chrono::high_resolution_clock::now();
auto start = std::chrono::time_point_cast<std::chrono::microseconds>(startTimept).time_since_epoch().count();
auto end = std::chrono::time_point_cast<std::chrono::microseconds>(endTimept).time_since_epoch().count();
auto duration = end - start;
double ms = duration * 0.001;
std::cout << duration << "us (" << ms << "ms)";
}
private:
std::chrono::time_point<std::chrono::high_resolution_clock> startTimept;
};
int main()
{
std::unordered_map<std::string, std::string>::iterator found, start, nFound;
//ADDS PAIRS OF SENTENCE INTO A MAP
std::unordered_map<std::string, std::string> sortMap =
{ { "these", "pairs" }, { "the", "correct" }, { "pairs", "makes" }, { "correct", "sentence" }, { "makes", "the" } };
std::unordered_map<std::string, std::string> swapMap =
{ { "pairs","these" }, {"correct", "the"}, { "makes", "pairs" }, {"sentence", "correct" }, {"the", "makes"} };
//CREATES CONTAINER TO STORE COMPLETE SENTENCE
std::list<std::string> resultSeq;
start = sortMap.begin();
//ADD STARTING WORDS INTO THE LIST
resultSeq.push_back(start->first);
resultSeq.push_back(start->second);
//TEMP POINTER TO SOUGHT WORD
found = sortMap.find(start->second);
//THIS IS THE FUNCTION I AM TRYING TO TEST
{
Timer timer();
for (auto it = sortMap.begin(); it != sortMap.end(); ++it) {
if (it == found) {
resultSeq.push_back(it->second);
found = sortMap.find(it->second);
it = sortMap.begin();
}
}
}
for (std::list<std::string>::iterator hard = resultSeq.begin(); hard != resultSeq.end(); ++hard)
{
std::cout << (*hard) << std::endl;
}
__debugbreak;
}
If anyone can spot what i'm doing wrong or offer any links to help with performance measuring that would be very helpful!
My personal approach, if it's just for quick debugging purposes, would be to use std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();. Since it's pretty wordy, I'd recommend making a wrapper function for it. Anyway, this simply returns the time in milliseconds since 1970 (not sure about that). Then you just stick one before the function and one after it, cout the difference and you have the milliseconds that the function took to execute.
You should use a std::steady_clock to measure time differences. The std::system_clock can be anything and does not need to be monotonic. The same goes for std::high_resolution_clock.
The high_resolution_clock is not implemented consistently across
different standard library implementations, and its use should be
avoided. It is often just an alias for std::chrono::steady_clock or
std::chrono::system_clock, but which one it is depends on the library
or configuration. When it is a system_clock, it is not monotonic
(e.g., the time can go backwards). For example, for gcc's libstdc++ it
is system_clock, for MSVC it is steady_clock, and for clang's libc++
it depends on configuration.
Further, to encapsulate time measuring, you can take advantage of C++'s RAII mechanism:
#include <chrono>
#include <type_traits>
#include <iostream>
template <typename Resolution = std::chrono::duration<double,std::micro>>
class Stopwatch {
typedef std::chrono::steady_clock Clock;
private:
std::chrono::time_point<Clock> last;
public:
void reset() noexcept {
last = Clock::now();
}
Stopwatch() noexcept {
reset();
}
auto operator()() const noexcept {// returns time in Resolution
return Resolution(Clock::now() - last).count();
}
~Stopwatch() {
// bad encapulation, you should reconsider this design!
// e.g. take a std::function as argument to the constructor and call it here
std::cout << (*this)() << "\n";
}
};
int main() {
{ // the block I want to measure
Stopwatch sw;
(void)(1+2+3); // some costly operation
} // end of measured block
}
i am trying to create a little clock for my game-project.
I am using the chrono-high-resolution-clock.
However, after declaring the variable inside my header file "gameTime.hpp", when referencing it in my source-file "gameTime.cpp", i get a segfault.
Hope anyone can help (and if the answer should be trivial: sorry, but the search i did on the subject didn't help me)
Here is the code:
header-file:
class GameTime
{
private:
std::chrono::high_resolution_clock::time_point mTime;
std::chrono::high_resolution_clock::time_point mLastTime;
double mTimeSpan;
public:
GameTime();
~GameTime();
void init();
double timePassed();
};
Source-file:
GameTime::GameTime()
{
}
void GameTime::init()
{
mTime = std::chrono::high_resolution_clock::now();
mLastTime = std::chrono::high_resolution_clock::now();
}
double GameTime::timePassed()
{
mTime = std::chrono::high_resolution_clock::now();
mTimeSpan = std::chrono::duration_cast<std::chrono::milliseconds>(mTime - mLastTime).count();
mLastTime = std::chrono::high_resolution_clock::now();
return mTimeSpan;
}
and the main-function: (it was pointed out that i should include this)
double frameTime;
GameTime* gameTime;
gameTime->init();
while(game->running())
{
frameTime = gameTime->timePassed();
std::cout << frameTime << std::endl;
}
The segfault happens inside the init() function, when i try to set a value for mTime.
Thanks in advance!
okay, the problem was that in my main-function, i only created a pointer, but not a real instance of the class GameTime.
The working code now looks like the following:
(main.cpp)
GameTime *gameTime = nullptr;
int main()
{
gameTime = new GameTime();
gameTime->init();
while(game->running())
{
frameTime = gameTime->timePassed();
std::cout << frameTime << std::endl;
}
return 0;
}
In my class-implementations, everything was fine.
I'm trying to create a step sequencer in C++ that will eventually send out MIDI data. I created it by having a clock on its own thread that calculates the amount of time since the last beat, and if it is time for the next beat, it writes a piece of data to the console.
However, I find that no matter what I set the BPM to, I get messages at a rate that is obviously too slow. I can't seem to figure out why the timing on this thread is wrong, and it doesn't help that I'm not terribly familiar with how the std::chrono library works. Thoughts?
Code below:
#include <thread>
#include <mutex>
#include <chrono>
#include <vector>
#include <iostream>
class StepSequencer {
public:
StepSequencer();
~StepSequencer();
void run();
void setBeatsPerMinute(float bpm);
void addNote(int noteValue, int beatIndex);
void playNote(int beatIndex);
protected:
int mNumberOfBeatBins;
int mSequencerPlayhead;
float mBeatsPerMinute;
float mSecondsPerBeat;
std::vector<int> mBeatBins;
std::mutex mMutex;
std::thread mSequencerThread;
bool mRunSequencerThread;
std::chrono::time_point<std::chrono::system_clock> mLastBeatTime;
std::chrono::time_point<std::chrono::system_clock> mCurrentTime;
};
#include "stdafx.h"
#include "StepSequencer.h"
StepSequencer::StepSequencer() {
mNumberOfBeatBins = 16;
for(int i = 0; i < 16; i++) {
mBeatBins.push_back(0);
}
mBeatsPerMinute = 0;
mSecondsPerBeat = 1;
mLastBeatTime = std::chrono::system_clock::now();
mCurrentTime = std::chrono::system_clock::now();
mSequencerPlayhead = 0;
mRunSequencerThread = false;
mSequencerThread = std::thread(&StepSequencer::run, this);
}
StepSequencer::~StepSequencer() {
if(mSequencerThread.joinable()) {
mSequencerThread.join();
}
}
void StepSequencer::run() {
mRunSequencerThread = true;
while(mRunSequencerThread) {
mCurrentTime = std::chrono::system_clock::now();
mMutex.lock();
if (std::chrono::duration_cast<std::chrono::seconds>(mCurrentTime - mLastBeatTime).count() > mSecondsPerBeat) {
mSequencerPlayhead++;
mSequencerPlayhead = mSequencerPlayhead % mNumberOfBeatBins;
playNote(mSequencerPlayhead);
mLastBeatTime = std::chrono::system_clock::now();
}
mMutex.unlock();
this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
void StepSequencer::setBeatsPerMinute(float bpm) {
mMutex.lock();
mBeatsPerMinute = bpm;
if(mBeatsPerMinute > 0) {
mSecondsPerBeat = 60.0 / mBeatsPerMinute;
}
else {
mSecondsPerBeat = 1;
}
mMutex.unlock();
}
void StepSequencer::addNote(int noteValue, int beatIndex) {
mBeatBins[beatIndex] = noteValue;
}
void StepSequencer::playNote(int beatIndex) {
std::cout << mBeatBins[beatIndex] << std::endl;
}
std::chrono::seconds has a representation of 'A signed integral type of at least 35 bits'. So you are going to get a value of count() which increments only once per second, giving the option of 60,30,20,15,12, etc. beats per minute.
Work in milliseconds or use a custom duration which is backed by a floating point value instead.
I am creating a program that reads in data about fireworks from an XML file (such as type, colour, time in milliseconds it launches and how long it lasts for etc). This then displays the fireworks display using openGL in a loop.
My approach to this is to have a manager class, that takes in a vector of the xml read fireworks and moves them between 3 different vectors: inactiveFireworks (those that are yet to fire), activeFireworks (those that need to be animated) and depletedFireworks (those that will be pushed back to inactiveFireworks when the display is run).
To check to see if a firework needs to be fired, I need to work out the difference between the time the firework manager was called and the current time of the program and multiply that by 1000 to get milliseconds.
eg: if a firework is due to fire at 3000, it will be called 3 seconds in to the existence of the fire work manager.
Unfortunately, I get an unhandled exception error at this point and I'm not sure why...
timeDifference = difftime(time(¤tTime),initTime) * 1000;
here is the header file:
#ifndef FWORKMANAGER_H
#define FWORKMANAGER_H
#include <Time.h>
#include <vector>
#include "firework.h"
class fworkManager
{
private:
time_t initTime;
time_t currentTime;
double timeDifference;
std::vector<firework*> inactiveFireworks;
std::vector<firework*> activeFireworks;
std::vector<firework*> depletedFireworks;
public:
fworkManager(std::vector<firework*> fListIn);
void drawAllFireworks();
void evolve();
void fireInactiveFireworks();
void moveActiveFireworks();
void moveDepletedFireworks();
void reset();
};
#endif
And here is the CPP.
#include <vector>
#include "LUtil.h"
#include "fworkManager.h"
fworkManager :: fworkManager(std::vector<firework*> fListIn){
inactiveFireworks = fListIn;
time (&initTime);
}
//animates fireworks
void fworkManager::evolve(){
//check time against inactiveFireworks
fireInactiveFireworks();
moveActiveFireworks();
moveDepletedFireworks();
reset();
}
//draws fireworks as they come up
void fworkManager::drawAllFireworks()
{
std::vector<firework*>::iterator i;
for(i=activeFireworks.begin(); i != activeFireworks.end(); i ++)
{
(*i) -> draw();
}
}
//if fireworks are ready to fire, push them to active list
void fworkManager::fireInactiveFireworks()
{
timeDifference = difftime(time(¤tTime),initTime) * 1000;
std::vector<firework*>::iterator i;
for(i = inactiveFireworks.begin(); i != inactiveFireworks.end();)
{
if((*i) -> getBegin() <= timeDifference)
{
activeFireworks.push_back(*i);
(*i) -> explode();
i = inactiveFireworks.erase(i);
}else{
++i;
}
}
}
//animate each firework in the active list
void fworkManager::moveActiveFireworks()
{
std::vector<firework*>::iterator i;
for(i = activeFireworks.begin(); i != activeFireworks.end(); i++)
{
(*i) -> evolve();
}
}
//move fireworks that have met their duration requirement to the depleted list.
void fworkManager::moveDepletedFireworks()
{
std::vector<firework*>::iterator i;
for(i = activeFireworks.begin(); i != activeFireworks.end();)
{
if((*i) -> getLifeSpan() >= (*i) -> getDuration() )
{
depletedFireworks.push_back(*i);
i = activeFireworks.erase(i);
}else{
++i;
}
}
}
//repopulates the inactive firework list and resets the time difference. Allows animation to loop.
void fworkManager::reset()
{
if(inactiveFireworks.empty() && activeFireworks.empty())
{
time (&initTime);
std::vector<firework*>::iterator i;
for(i=depletedFireworks.begin(); i != depletedFireworks.end();)
{
(*i) -> reset();
inactiveFireworks.push_back(*i);
i = depletedFireworks.erase(i);
}
}
}
Many Thanks for any insight offered.
I am trying to make a Clock with the timeGetTime function and some others. But I keep getting an exception error. I know mayby the quality of the program is not really good, but I was just trying to get it work. It's supposed to be a singleton. I hope you can help me!
// The Clock header file
// The Clock API for meassuring time.
#include<Windows.h>
#include<WinBase.h>
#include<MMSystem.h>
class cTime
{
private:
double m_Ns;
double m_Ms;
double m_S;
public:
// Set Values
void SetN(double N) {m_Ns = N;}
void SetM(double M) {m_Ns = M;}
void SetS(double S) {m_Ns = S;}
// Get Values
double GetN() {return m_Ns;}
double GetM() {return m_Ms;}
double GetS() {return m_S;}
// GetTime functions
//int GetDiffrenceNs();
//int GetDiffrenceMs();
//int GetDiffrenceS();
};
class cClock
{
private:
cTime m_CurrentTime; // CurrentTime object
static cClock* m_pClock; // Pointer to only instance
cTime m_LastTime; // LastTime object
bool m_PerformanceCounter; // Set to true if the performance counter is available
double m_Frequency; // Tells the frequenty of the PerformanceCounter. The value that the PerformanceCounter will increase each second.
double m_CounterTime; // The Counter of the PerformanceCounter.
double m_Trillingstijd; // How long one count of the performance counter will take.
public:
static cClock* GetClock();
cTime CurrentTime(); // Get the CurrentTime.
cTime LastTime(); // Get the LastTime.
// Virtual destructor.
virtual ~cClock();
protected:
// Protected constructor.
cClock();
};
// The clock cpp file
#include "Clock.h"
cClock* cClock::m_pClock = 0;
cClock* cClock::GetClock()
{
//BOOL perf_flag; // Timer Selection Flag
//double time_factor; // Time Scaling Factor
//LONGLONG last_time; // Previous timer value
//LONGLONG perf_cnt;
if (QueryPerformanceFrequency((LARGE_INTEGER *) &m_pClock->m_Frequency))
{
QueryPerformanceCounter((LARGE_INTEGER *) &m_pClock->m_CounterTime);
m_pClock->m_PerformanceCounter = true;
m_pClock->m_Trillingstijd=1.0/m_pClock->m_Frequency;
double LastedSeconds = m_pClock->m_CounterTime/m_pClock->m_Frequency;
m_pClock->m_LastTime.SetN(LastedSeconds*1000000);
m_pClock->m_LastTime.SetM(LastedSeconds*1000);
m_pClock->m_LastTime.SetS(LastedSeconds);
}
else
{
m_pClock->m_PerformanceCounter = false;
double LastedMiliseconds = timeGetTime();
m_pClock->m_LastTime.SetN(LastedMiliseconds*1000);
m_pClock->m_LastTime.SetM(LastedMiliseconds);
m_pClock->m_LastTime.SetS(LastedMiliseconds/1000);
}
return cClock::m_pClock;
}
cTime cClock::LastTime()
{
return m_LastTime;
}
cTime cClock::CurrentTime()
{
if(m_PerformanceCounter)
{
QueryPerformanceCounter((LARGE_INTEGER *) &m_CounterTime);
double LastedSeconds = m_CounterTime/m_Frequency;
m_CurrentTime.SetN(LastedSeconds*1000000);
m_CurrentTime.SetM(LastedSeconds*1000);
m_CurrentTime.SetS(LastedSeconds);
}
else
{
int LastedMiliseconds = timeGetTime();
m_CurrentTime.SetN(LastedMiliseconds*1000);
m_CurrentTime.SetM(LastedMiliseconds);
m_CurrentTime.SetS(LastedMiliseconds/1000);
}
m_LastTime = m_CurrentTime;
return m_CurrentTime;
}
This is my main, really simple but I just tried to get it to work but it doesn't...
#include "Clock.h"
#include<iostream>
using namespace std;
int main()
{
cClock* Clock = cClock::GetClock();
cTime Test = Clock->CurrentTime();
cout << Test.GetN();
cout << Test.GetM();
cout << Test.GetS();
int temp;
cin >> temp;
return 0;
}
It seems that the method cClock* cClock::GetClock() uses m_pClock without initializing it (it is still 0).
You are never creating an instance of cClock, just accessing a null pointer to one.
If you really think a singleton is a good idea, then cClock::GetClock() will have to create one if it doesn't already exist; along the lines of
cClock* cClock::GetClock()
{
if (!m_pClock) {
m_pClock = new cClock;
}
// remainder of function
return m_pClock;
}
Note that this isn't thread-safe, and also introduces a memory leak. Singletons are difficult to implement in C++, and best avoided unless there is a genuine reason for wanting one. I would move the logic of GetClock() into a public constructor, and allow client code to create and destroy clock objects as it sees fit.