Skip to content

Instantly share code, notes, and snippets.

@rubentorresbonet
Created September 3, 2014 09:45
Show Gist options
  • Save rubentorresbonet/f47b76c0794719a6ca1a to your computer and use it in GitHub Desktop.
Save rubentorresbonet/f47b76c0794719a6ca1a to your computer and use it in GitHub Desktop.
/*
* PermanentTimer.cpp
*
* Created on: 18.08.2014
* Author: ruben.torres
*/
#include <map>
#include <fstream>
#include <string>
#include <cocos2d.h>
#include <cereal/archives/binary.hpp>
#include "PermanentTimer.h"
using namespace cocos2d;
// -------------------------------------------------------------------
PermanentTimer::PermanentTimer()
{
filePath = cocos2d::CCFileUtils::sharedFileUtils()->getWriteablePath() + "pt.map";
}
// -------------------------------------------------------------------
void
PermanentTimer::setTimer(std::string key, time_t seconds)
{
// 1. Add to "now" our time in seconds to get "then".
time_t then = time(NULL) + seconds;
// 2. Set it into our timers variable.
timers.emplace(key, then);
// We don't save automatically to avoid performance issues.
}
// -------------------------------------------------------------------
PermanentTimer::TimerStatus
PermanentTimer::checkTimer(std::string key)
{
auto search = timers.find(key);
// 1. Does it exist?
if (search == timers.end()) {
return TimerStatus::NOT_FOUND;
}
// 2. It exists; calculate times.
time_t now = time(NULL);
time_t then = search->second;
// 3. Expired?
if (now > then) {
// Return that it expired.
return TimerStatus::EXPIRED;
}
// 4. Otherwise it didn't expire.
return TimerStatus::ALIVE;
}
// -------------------------------------------------------------------
time_t
PermanentTimer::remainingSeconds(std::string key)
{
auto search = timers.find(key);
// 1. Does it exist?
if (search == timers.end()) {
return 0;
}
// 2. It exists; calculate times.
time_t now = time(NULL);
time_t then = search->second;
// 3. Difference.
time_t delta = then - now;
// 4. Return.
if (delta < 0) {
return 0;
}
return delta;
}
// -------------------------------------------------------------------
void
PermanentTimer::removeTimer(std::string key)
{
// 1. Search for it.
auto search = timers.find(key);
// 2. If it does exist, remove it.
if (search != timers.end()) {
timers.erase(search);
}
}
// -------------------------------------------------------------------
void
PermanentTimer::init()
{
// 1. Try to open the file for reading.
std::ifstream ifs(filePath);
// 2. If opened, load it.
if (ifs.is_open()) {
try {
cereal::BinaryInputArchive iarchive(ifs);
iarchive(*this);
} catch (...) {
save();
}
}
// 3. Close the file.
ifs.close();
}
// -------------------------------------------------------------------
void
PermanentTimer::save()
{
// 1. Try to open the file for writing.
std::ofstream ofs(filePath, std::ios::out | std::ios::trunc);
CCPAssert(ofs.is_open(), "PermanentTimer::save(): important! Could not save");
if (ofs.is_open() == false) {
//throw std::runtime_error("PermanentTimer::save(): could not save"); // I don't think we want the client to crash.
return;
}
// 2. Save.
try {
cereal::BinaryOutputArchive oarchive(ofs);
oarchive(*this);
} catch (...) {
CCPAssert(false, "PermanentTimer::save(): exception");
}
// 3. Close.
ofs.close();
}
// -------------------------------------------------------------------
void
PermanentTimer::removeAllTimers()
{
timers.clear();
int res = std::remove(filePath.c_str());
CCPAssert(res == 0, "PermanentTimer::clear(): remove file failed");
}
// -------------------------------------------------------------------
/*
* PermanentTimer.h
*
* Created on: 18.08.2014
* Author: ruben.torres
*/
#pragma once
#include <cereal/types/string.hpp>
#include <cereal/types/map.hpp>
/**
* This class handles permanent timers; useful
*/
class PermanentTimer {
public:
PermanentTimer();
~PermanentTimer() = default;
enum class TimerStatus {
NOT_FOUND = 0,
ALIVE = 1,
EXPIRED = 2
};
/**
* Loads the permanent timers into the timers variables.
* @param forceLoad if true, it will be loaded even if it's been previously already loaded.
*/
void init();
/**
* Sets a timer for X seconds (starting from now).
* @param key the name of the timer.
* @param seconds
*/
void setTimer(std::string key, time_t seconds);
/**
* Checks whether a timer expired.
*
* @param key
* @return a TimerStatus with the status.
*/
TimerStatus checkTimer(std::string key);
/**
* Returns the remaining seconds of that key.
* @param key
* @return 0 if expired or doesn't exist.
*/
time_t remainingSeconds(std::string key);
/**
* Removes a timer to tidy it up a little.
*
* @param key
*/
void removeTimer(std::string key);
/**
* Saves our timers variable into permanent storage.
*/
void save();
/**
* Serialize method for cereal and storing timers.
*/
template<class Archive>
void serialize(Archive & archive, unsigned int version)
{
archive( timers );
}
/**
* Clears our timers variable and erases the file.
*/
void removeAllTimers();
private:
/**
* Timers variable.
*/
std::map<std::string, time_t> timers;
/**
* The path of the file for loading & saving.
*/
std::string filePath;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment