Originally Posted by
whoie
You're right, it does sound difficult, but when you get past the initial fuzziness, it's not that difficult at all. It just seems a lot harder than it really is when you do it for the first time. You're going to have to decide whether replacing ostringstream is going to be worth the learning investment. If you are using the SDL libraries reasonably successfully, then you can handle iostreams.
You could make cMessage a child of std::streambuf, but you will end up dropping the PostMessage and OnWrite member functions. Instead, PostMessage will be mostly replaced by overflow and OnWrite will be mostly replaced by sync. It's going to take a little more surgery to fill out the rest, but that's a start.
Does this sound like it's worth getting rid of all the ostringstream uses or not?
Yeah, you're right, I have been programming only for about one year and each time I found the solution for a specific problem, it will be very easy for almost all similar problems.
So first, I should declare cMessage as a child of std::streambuf, I suppose.
I've read some tutorials about streambuf, I know that streambuf is a virtual base class that I need to inherit, but I still don't have any idea how to achieve something like I said.
Yeah, it's worth to go on.
So this is the header, and I've declared it to be a child of std::streambuf, so what now?
Code:
#ifndef _CMESSAGE_H_
#define _CMESSAGE_H_
#include <SDL/SDL.h>
#include <string>
#include <streambuf>
#include "defines.h"
#include "CSurface.h"
#include "CFont.h"
#define MESSAGE_DURATION 1500
#define NUM_MESSAGES 8
#define CONSECUTIVESIX 0
#define NO_MOVES_AVAIL 1
#define SELECT_PIECE 2
#define THROW_DICE 3
#define INVALID_MOVE 4
#define EXTRA_MOVE 5
#define GET_ONPATH 6
#define SAFELY_HOME 7
class cMessage : public std::streambuf
{
private :
int X;
int Y;
int FontID;
std::string Message;
unsigned long StartTime;
public :
bool Active;
bool oneTime;
cMessage(int X, int Y, int ID);
void PostMessage(std::string Message, bool oneTime_flag = false);
void OnWrite(SDL_Surface *Surf_Display, SDL_Surface *Surf_Balloon);
static const char *GameMessage[NUM_MESSAGES];
};
#endif
Oh yeah, I've recently modified something in this class, so here it is.
Code:
#include "cMessage.h"
cMessage::cMessage(int X, int Y, int ID) : X(X), Y(Y), FontID(ID)
{
StartTime = 0;
Active = false;
oneTime = false;
}
void cMessage::PostMessage(std::string Message, bool oneTime_flag)
{
if(!Active)
{
StartTime = SDL_GetTicks();
this -> Message = Message;
Active = !oneTime_flag;
oneTime = oneTime_flag;
}
}
void cMessage::OnWrite(SDL_Surface *Surf_Display, SDL_Surface *Surf_Balloon)
{
if(Surf_Display == NULL || (!Active && !oneTime) || Surf_Balloon == NULL)
return;
if(StartTime + MESSAGE_DURATION > SDL_GetTicks() || oneTime)
{
CSurface::OnDraw(Surf_Display, Surf_Balloon, BALLOON_X, BALLOON_Y);
SDL_Color Fg = {0, 0, 0, 0};
CFont::FontControl.OnWrite(&Surf_Display, Message.c_str(), FontID, X, Y, &Fg, NULL, CFONT_BLENDED | CFONT_ALIGN_CENTER);
if(oneTime)
{
oneTime = false;
Active = false;
Message.clear();
}
}
else
{
Message.clear();
Active = false;
}
}
const char* cMessage::GameMessage[NUM_MESSAGES] =
{
", You threw two\nconsecutive sixes. Your\nbonus turn is canceled.",
", You Have No\nMoves Available. You have\nto skip your turn.",
",\nPlease select your piece.",
",\nPlease throw your dice.",
",\nThat is an invalid move!",
", You threw a\nsix, you'll get a\nbonus turn!",
", You threw a six,\nyou can now take\na piece on play.",
",\none of your pieces has\nmade it safely home!"
};