Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Clock Class/Time Class  (Read 4863 times)

0 Members and 1 Guest are viewing this topic.

KasHKoW

  • Newbie
  • *
  • Posts: 41
    • View Profile
Clock Class/Time Class
« on: June 18, 2011, 05:43:22 am »
Hi, I have limited time on finishing a project i'm doing. The problem that's slowing me down from finishing this is kinda integral to my overall abilities and what I want to do with SFML.

I basically need to know how to display time. The tutorial shows how to use this, just not how to actually display it. I've played with it for a few hours, and I would rather not play with it any longer as my time is very limited.

I've been trying to cast sf::Clock.GetElapsedTime into a sf::String so I can concatenate them and display it on the screen. This obviously doesn't work.

sf::Clock doesn't inherit drawable so it's not something you can draw... etc. I'm kinda lost and on top of that, I kinda hardly know what I'm doing.

Kian

  • Newbie
  • *
  • Posts: 44
    • View Profile
Clock Class/Time Class
« Reply #1 on: June 18, 2011, 08:38:12 am »
sf::Clock::GetElapsedTime() returns an Uint32 (32-bit unsigned integer) with the elapsed number of milliseconds (ms) that have passed since you started the clock (or the last time you reset it).

The reason you can't cast it to a string is because sf::String is meant to be used with different representations of, well, strings. Characters, not binary representations of numbers. When you write, say,
Code: [Select]
sf::String s;
s='a';
the character 'a' has a representation and a meaning. The representation is the binary code, a number in essence. The meaning is the letter a. For example,
Code: [Select]
char x = 97;
(x == 'a')
evaluates to true.

So, referring to your problem. Let's say you call GetElapsedTime(). You get a number like 1357, meaning it's been 1.357 seconds since the clock was started or reset. If you want to convert this to a string to write it out, you have to find a way of converting each digit into a character.

Thankfully, this is a common need, and there are many functions that do it. itoa() in the <cstdlib> header can do it, you can look up a reference for it here.

Given your number and a char array, it will fill the char array with a null terminated string with the depiction of the number in the appropriate base. You can then pass this array to sf::String, which can then do whatever you need it to do.

This will not format the time into a readable format, however. You'll need to massage the numbers to get them to read as time (meaning seconds, minutes, hours).

For an example of how to do it:
Code: [Select]
#include <cstdlib>
#include <SFML/System.hpp>

int main()
{
    sf::Clock Clock;
    sf::String s;
    char buffer[10];
    Uint32 time;

    time=Clock.GetElapsedTime();
    while(time<5000)
    {
       
        int hours = time/3600000; // We get the number of hours, there's 3600000 milliseconds in each hour
        time -= hours * 3600000; // Now that we know the number of hours, we remove that number of milliseconds from time so we can figure out the minutes left over.
        itoa(hours, buffer, 10);
        s=buffer;      // I took a quick look at String's documentation, I think this is valid.
                       // You might have to do a bit more magic to get the chars into the string, but at least buffer now has the right values
        s+=" hours, "; //s only contained a number (written in characters), now it contains the string "hh hours, " where hh means the number of hours

        int minutes = time / 60000 ; // There's 60000ms in each minute
        time -= minutes * 60000;
        itoa(minutes, buffer, 10);
        s+=buffer; s+=" minutes, ";

        int seconds = time / 1000; // Naturally, there are 1000ms per second
        time -= seconds * 1000;
        itoa(seconds, buffer, 10);
        s+=buffer; s+=".";
        itoa(time, buffer, 10);
        s+=buffer; s+=" seconds.\n";

        // Right now, s contains a string that looks like "hh hours, mm minutes, ss.mmm seconds."
        // You can now attempt to display the string in whatever manner best suits your needs.
        time=Clock.GetElapsedTime();
    } // The loop will run for 5 seconds before exiting.
       
    return 0;
}

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Clock Class/Time Class
« Reply #2 on: June 18, 2011, 09:34:00 am »
Quote
Thankfully, this is a common need, and there are many functions that do it. itoa() in the <cstdlib> header can do it, you can look up a reference for it here.
Well, there's also a (better) C++ way to do this : using stringstream. (Some of these XtoY C function will return 0 when it fails but 0 can also be a valid answer so you can't be sure if it fails or not. With stringstream you always can know if it fails or not by testing the stream as a boolean.)

So it'll look like :
Code: [Select]

#include <sstream>
:
:
std::string HumanReadableTime(Uint32 time) {
  const int hours   = time / 3600000;
  time -= hours * 3600000;
  const int minutes = time / 60000;
  time -= minutes * 60000;
  const int seconds = time / 1000;
  time -= seconds * 1000;
  const int millis  = time;
 
  std::stringstream ss;
  ss << hours << ":" << minutes << ":" << seconds << ":" << millis;
  return ss.str();
}


With this function you can display the time wherever you want (console, window, ...) as it returns a std::string.

Then the conversion to sf::String is very easy.
SFML / OS X developer

KasHKoW

  • Newbie
  • *
  • Posts: 41
    • View Profile
Clock Class/Time Class
« Reply #3 on: June 19, 2011, 12:59:04 pm »
there's no easier way than this??

Thanks both methods are nice.

Wow, i don't know which one to use. Obviously the more compact one is better, but the one using c is very good too. I guess I will mess with both of 'em (4 some weird reason).

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Clock Class/Time Class
« Reply #4 on: June 19, 2011, 01:46:38 pm »
Quote from: "KasHKoW"
there's no easier way than this??
You mean something is obscure ? Just ask if you don't understand any part of the code.

Quote from: "KasHKoW"
I guess I will mess with both of 'em (4 some weird reason).
I wouldn't do that. It won't help much.

Quote from: "KasHKoW"
Obviously the more compact one is better, but the one using c is very good too.
If I may, these are not valid arguments to choose any of the two solutions. 'Compact' doesn't mean good same goes for 'written in X' (even if X is a very good programming language) : you can do the worst code ever with any language.

Anyway, good luck with your project.
SFML / OS X developer

KasHKoW

  • Newbie
  • *
  • Posts: 41
    • View Profile
Clock Class/Time Class
« Reply #5 on: June 19, 2011, 06:44:28 pm »
True, I still want to use both though... I guess I want to know the libraries of each language.  I understand it perfect... When I first saw them, they were daunting. But then I took like 5 minutes to actually read through the code and understand it perfectly. I plan to make a class that's probably going to be reusable, where you can show seconds, minutes, couple(of them) or all three.

Any better ideas for this class, I would love to hear... I'm all ears.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Clock Class/Time Class
« Reply #6 on: June 19, 2011, 07:14:13 pm »
Quote from: "KasHKoW"
Any better ideas for this class, I would love to hear... I'm all ears.
Maybe you could reuse the library Boost.DateTime.

By the way, it might be that I am going to implement a very similar Time class for my library, mainly to convert between seconds and milliseconds. If I really did this, I could also provide an easy way to retrieve minutes. See this thread for more information.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: