Precision, precision…
One of the things I have been writing for Flexposure is the RAPI which is short for Remote API. The RAPI (which you should mispronounce when you are among the opposite sex) is nothing more than a thin communication layer which can be used on virtual any other protocol like UDP and TCP but also on some industrial standards which are used by hardware (even my worst enemy: RS232 AKA comport).
Even though I'm not racist I hate the diversity of compilers and OS so I decided to use Boost for all the timing relevant functions. Within boost you have two types of clock:
boost::posix::second_clockboost::posix::microsec_clock
Thinking which one I wanted I decided not to go for the high-performance clock. I only want to know if a message had timed out and if I should send another one.
A basic example of the code would be this:
class SendTask : public IClientTask
{
public:
SendTask()
: m_SendTimestamp(boost::posix::second_clock::universal_time())
, m_SendInterval(boost::posix::seconds(1))
{
}
void Tick()
{
auto currentTime = boost::poxix::second_clock::universal_time();
bool sendAgain = m_SendTimestamp < currentTime;
if(sendAgain)
{
// ...
// Send message again
// ...
// Increase the next timestamp.
m_SendTimestamp = currentTime + m_SendInterval;
}
}
private:
boost::posix::ptime m_SendTimestamp;
// The default delay is one second (decided by constructor)
boost::posix::time_duration m_SendInterval;
};
Timing the above code I was surprised to see that sending a message using UDP over the loopback took about 0.5 seconds, which was at least ten times more than what I had expected. After checking my code multiple times and not finding anything I could only come to the conclusion that somewhere in my code I made a wrong assumption. So I wrote a little test to at least ensure it had nothing to do with boost and to ensure it was my code.
int main()
{
while(true)
{
std::cout << boost::posix::second_clock::universal_time() << std::endl;
}
return 0;
}
Removing all the duplicate entries that were printed I found out that the time difference between each timestamp was around 0.5 seconds. This would explain why it would take so long before it would send again. I told its resend delay is 100 milliseconds it would take at least 0.5 seconds because of the problem with the resolution/precision.
But I was using the loopback (sending to 127.0.0.1) and although messages can get lost there it should not happen that often. Sure I could replace everything with a faster clock but I wanted to know why this delay occurred. Taking another look at the send code I noticed that the following line:
bool sendAgain = m_SendTimestamp < currentTime;
If the send time is in the past it would send and this is also true for the very first time. Changing the code so that it checks if the next send time is less or equal than the current time fixed it and the performance increased to 0.005 milliseconds since it no longer had to wait for the first time out.
Sure I could have saved myself a lot of trouble by replacing the clock with the higher resolution variant (after striking concurrency of my list this was my next guess) but I rather spend a few hours on figuring out what exactly is going on. It takes time now but in the end it should save me time when I come before the decision which clock to choose.
Invalid code: from wstring to string
Before I start let me make one thing clear: I used to do it like this as wel.
When you need to convert an std::wstring to an std::string you should not simply do the following:
std::wstring input = L"Hello World"; std::string output; output = std::string(input.begin(), input.end());
The above code is valid, but incorrect. A string is nothing more than a fancy array (just like a vector) but who is specialized for our basic usage of text (which is concatination and using the stream operators). If you look at std::wstring as a std::vector<wchar_t> and a std::string as a std::vector<char> then you should come to realisation that the above code performs an implicit cast (from wchar_t to a char).
If you use std::wstring to store UTF8 then there is no problem, but if you use it to store UTF16 then you do have a problem as you might lose some information. Also keep in mind that it is perfectly fine to store UTF16 in an std::string but then you should realize that every 2 elements in the string is one single character.
More correct (but still incorrect) would be:
// Just making certain that wchar_t is 16 bits.
assert(sizeof(wchar_t) == 2);
assert(sizeof(char) == 1);
std::wstring input = L"Hello world";
std::string output;
std::wstring::const_iterator it = input.cbegin();
while(it != input.cend())
{
output += ((*it) & 0xFF00) >> 8; // Add the most significant bits.
output += ((*it) & 0x00FF) >> 0; // Add the least significant bits
// Going to the next wchar_t
++it;
}
Service your code
In the past week a friend of mine tweeted that debugging took so damn long, because he had to compile a lot of code, load the game and wait until the level was loaded before he could test one specific feature. From experience this can easily take more then 10 minutes of your time, while to solution is only a boolean check that needs to be inverted. One of the solutions I proposed was to put it in a DLL and dynamicly load (and re-load) that code until you have solved the problem and as I was typing it out I realized that this could be applied more often.
If you create a core application against which does only a few core elements (like basic rendering and providing input) and you put the rest in DLL which can dynamically be loaded and unloaded you will in theory never have to touch the core application again. The rest are all buildingblocks which are continuesly improved. If you do this, you can easily rollout (or rollback) features. Even cooler is that with another product you only have to write a few new buildingblocks (assuming you continuesly improve your old buildingblocks), create new content and your done.
If after a few years you want to re-release your game but you want to use the improved render, all you need to do is replace it. No more memory leaks the old version had
But for that we need to continuesly serivce our code, something I believe is rarely done.
Never release poor quality!

One of the rules I have adopted is that I will never (if the choice is mine to make) release poor quality software/games/code/content/etc. I hate that rule with a passion even though I use it constantly. The reason why I hate it is because I often promise to release some code in the near future but then decide I would rather break my promise than release poor quality.
The reason why I don't want to release poor quality code can be summarized as followed:
- Improving the quality of an existing product is hard. If anyone (me included) would use my code then there is good chance that some of the poorer quality rubs off on the other code, making the final product of lower quality.
- Never feed a critic except his own words. I can't and won't recall the amount of times that I complained about some piece of code written by myself or others. If I complain about the code, why wouldn't others?
- Poor craftmanships reflects poorly.
- Releasing poor quality once, sets a precedent to lower the bar the next time you need to release something
And for those reasons only a shocking 10% of my work is released and that excludes any projects that I write pure for testing. When I look at my blog I know that I have more drafts (articles I wrote, but never posted) than actually posted articles.
So if you were ever wondering when I would release the code, then there is good chance that I won't. And for that I'm sorry. (but frankly you should be glad I don't release it
)
Extending exceptions
Sometimes you have a function which needs to communicate back on failure through special exceptions as you want to program have the option to fix certain functions. For example a formula whose input parameter is bad (example: begin date is after the end date) or when the database throws up or anything.
Now you could do the following:
public class EndDateBeforeBeginDateException : Exception { }
class example
{
void SomethingWithTime(DateTime begin, DateTime end)
{
if (begin > end) throw new EndDateBeforeBeginDateException();
// ... do something with time ....
}
void DemonstrateFunctionTriesToCorrectInsteadOfFail()
{
DateTime input_begin = new DateTime();
DateTime input_end = input_begin.AddDays(-1); // WRONG DATE ON PURPOSE!
do
{
try
{
SomethingWithTime(input_begin, input_end);
}
catch (EndDateBeforeBeginDateException)
{
// Date was most likely wrong ask user
var r = MessageBox.Show("The end date was before the begin date."
+ "Do you want to switch them and try again?",
"Switch dates?",
MessageBoxButtons.YesNo);
if (r != DialogResult.No) { return; } // quit function
var temp = input_begin;
input_begin = input_end;
input_end = temp;
continue; // Try again now
}
} while (false);
}
}
But what if you have a lot of parameters. You don't want to create thousands of exceptions. Well, you can try using tagged exceptions which looks like this.
public class TaggedException<T> : Exception { }
struct _EndDateBeforeBeginDateTag{}
struct _SameDateTag {}
struct _TimeDoesNotExistTag {}
struct _ThinkOfATagOnYourOwn {}
class example
{
void SomethingWithTime(DateTime begin, DateTime end)
{
if (begin > end) throw new TaggedException<_EndDateBeforeBeginDateTag>();
if (begin == end) throw new TaggedException<_SameDateTag>();
// ... do something with time ....
}
void DemonstrateFunctionTriesToCorrectInsteadOfFail()
{
DateTime input_begin = new DateTime();
DateTime input_end = input_begin.AddDays(-1); // WRONG DATE ON PURPOSE!
do
{
try
{
SomethingWithTime(input_begin, input_end);
}
catch (TaggedException<_EndDateBeforeBeginDateTag>)
{
// Date was most likely wrong ask user
var r = MessageBox.Show("The end date was before the begin date."
+ "Do you want to switch them and try again?",
"Switch dates?",
MessageBoxButtons.YesNo);
if (r != DialogResult.No) { return; } // quit function
var temp = input_begin;
input_begin = input_end;
input_end = temp;
continue; // Try again now
}catch (TaggedException<_SameDateTag>)
{
// Force the user to change one date
}catch (TaggedException<_ThinkOfATagOnYourOwn>)
{
// Tag seems obvious enough *wink*
}
} while (false);
}
}
Now you only have one Exception in your code though you can quickly and without having to write much code.
(And if you are smart you store extra info the tag which is stored in the exception).
The same trick also works in C++ using templates.
Comments
This part is almost straight from my programming style document.
This might sound stupid, but try to comment every other line (unless you have a lot of repeating or similar tasks). By doing so you get two advantages:
- Someone unskilled in programming or unfamiliar with what you are doing is able to read your code.
- You know what you are doing
The first advantage is important unless you are working alone and never expect to see your code again. In that case you should really ask yourself if you should even be writing that code.
The second one is important even if you have no trouble reading code. Let's take a look at the following example.
for(int index_person = 0; index_person < persons.size(); ++index_person)
{
for(int index_kids = 0; index_kids < persons[index_person].kids.size(); ++index_kids)
{
/* ... */
}
}
And then take a look at this example:
/* Iterating through the persons in the lists */
for(int index_person = 0; index_person < persons.size(); ++index_person)
{
/* Iterating through the kids of the persons in the list */
for(int index_kids = 0; index_kids < persons[index_person].kids.size(); ++index_kids)
{
/* checking if any of the persons in the list have a kid who is dead */
/* ... */
}
}
In the last example I only have to track back to the first comment prior to my line of code to know what I'm doing here. It's a pain to write so many comments but it makes code a whole lot easier to read.
Splash screens
I always have my doubts about splash screens. As far as I know the majority of the splash screens have no function. A minority does have a function (they do background loading).
The main purpose of splash screen is, in my opinion, advertising. For a few second the user sees the name of the application and the company behind it. I admit that you can use it to load things in the background, but showing a splash screen also takes time. In that case you are better off loading the application and showing a progress bar. At that point the user sees it as the application is loading content. If you are using a splash screen for that (and I'm going to assume it makes no difference in performance or time that it requires) than the users perceives it as an annoyance.
This is a weird thing. Because showing a splash screen that does nothing but is only showed for a 2 seconds after which the application starts loading is seemed to be less intrusive than a splash screen that takes longer but actually causes the application to load faster (it doesn't require two useless seconds).
So how do you create a splash screen?
First of all start with a small image (take the dimensions of the office 2007 splash screens), add some abstract art (not something complex). Then create a form without borders in C# that closes after a few seconds and then modify the program.cs so that it looks like this.
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Client
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new SplashScreen()); // load the splash screen
Application.Run(new MainWindow()); // load the application
}
}
}
I know it's a cheap trick, but it looks nice if you do it well. And most customers care a lot about appearance.
Events in C++
This week I have decided to do some little work on Nova as I would like to use it for a game. But I’m currently missing a GUI. Since writing a GUI is often a pain while a nice GUI is its weight worth in gold it was worth to invest some time in it.
One of the very first things I have decided on is that I want a good and proper event management system. I like how it is done in C#
myButton.Click += new EventHandler(this.myButton_Click);
However something equally nice doesn't exist in plain C++, so I have decided to write one.
struct GuiEvent
{
bool cancel;
GuiEvent() : cancel(false) {}
};
class Button
{
public:
Event<GuiEvent> OnDown;
Event<GuiEvent> OnUp;
void FireClickEvent()
{
size_t cycle = 0; GuiEvent e;
while(OnDown.Fire(cycle, e)) {
if(e.cancel == true) return;
}
e = GuiEvent(); cycle = 0;
while(OnUp.Fire(cycle, e));
}
};
class Application : public BaseEvent::Receiver<Application>
{
Button m_StartButton;
public:
Application()
{
RegisterEvent<GuiEvent>(m_StartButton.OnDown, &Application::StartDown);
RegisterEvent<GuiEvent>(m_StartButton.OnUp, &Application::StartUp);
m_StartButton.FireClickEvent();
}
void StartUp(GuiEvent& eventParam)
{
std::cout << "The start button was released" << "\n";
}
void StartDown(GuiEvent& eventParam)
{
// If you set event param to true the release will never be called
//eventParam.cancel = true;
std::cout << "The start button is pressed down" << "\n";
}
};
int main(int argc, const char* argv[])
{
Application myApp;
return 0;
}
The above is rather primitive as I have written it quickly, but it looks nice and is code that is easy to understand. For the full source click here (C++ example of events)
EULA of Visual Studio 2010 from dreamspark
Update 2010-12-02: Microsoft has fixed the EULA and it now has the "you can't use it for commercial purposes disclaimer". Thanks for pointing it out to me, WoongBin!
EULA: End User License Agreement
You know that annoying check box you need to check when you install new software or games? The one that says "I have read and agree with the EULA"? Do you ever read what it says above it? No? Oh...
Seriously. The EULA is important and you should read it... in some cases.
One of those cases was when I was browsing DreamSpark (free Microsoft development tools) which after registering and confirming you are a student (one of the few times I happily admit I'm a student) you can download all kind of free development tools at no charge with all features.
In general there is no such thing as free stuff. "Buy one and get another free" is not free, it is 50% discount when you buy two. Still I decided to check it out and to my surprise (actually, the school forum had point it out). There was also the new Microsoft Visual Studio 2010 Professional.
"Cool!!" was my first reaction, but after checking the site further out I noticed that Visual Studio 2008 and many others had a license that by downloading I agree to not use it for "commercial". Here is the section I refer to:
b. Restrictions. You may not use the Software:
• for commercial purposes (except as permitted under Section 3(d); or
• to develop or maintain Your own administrative or IT systems, or those of Your educational institution.
(Full Microsoft DreamSpark License)
However for some strange reason the above EULA was not on the screen of VS2010. So after downloading I checked if the installer had such a restriction and it did not. That means I now have a full and legal version of Visual Studio at no cost with no restrictions other than those you would have if you bought it.
For that I thank you Microsoft!
Solved undesired template specification
A while ago (why do I always start with that) I wrote an blog entry about undesired template specification, what to encounter and how to work around it.
Anyway here is a quick definition of two structures I will be using in the article:
/**
* I will be using the following structures throughout the article
*/
template <typename T> struct Vector3<T> {
union {
struct { T x, y, z; }
T array[3];
};
Vector3<T>() : x(0), y(0), z(0) {}
Vector3<T>(T nx, T ny, T nz) : x(nx), y(ny), z(nz) {}
};
template <typename T> struct Vector4<T> {
union {
struct { T x, y, z, w; }
T array[4];
};
Vector4<T>() : x(0), y(0), z(0), w(0) {}
Vector3<T>(T nx, T ny, T nz, T nw) : x(nx), y(ny), z(nz), w(nw) {}
};
typedef Vector3<unsigned int> Vector3u;
typedef Vector3<float> Vector3f;
typedef Vector4<unsigned int> Vector4u;
typedef Vector4<float> Vector4f;
struct SVertex
{
Vector4f pos;
Vector3f normal;
Vector2f texcoord;
};
Because of Brick (3D random dungeon generator that takes design into account) I have noticed that there is one thing I do failry often:
Vector3f position; SVertex vertex; /* Need to draw it, so I store position in vertex */ vertex.pos = position; // ERROR! Trying to assign Vector3f to Vector4f!!
And finally I used defines to do the conversion for me:
#define VEC3TOVEC4(v) Vector4f((v).x, (v).y, (v).z, 0) #define VEC4TOVEC3(v) Vector3f((v).x, (v).y, (v).z) /* New code becomes */ vertex.pos = VEC3TOVEC4(position); // Works
Of course the above code is not nice to look at and I find it even plain ugly, but it works. However I don't want to do that in future projects (it feels like a hack), I would need to define something like that for every type (float, double, unsigned int et cetera) and on top of that it generates warnings:
Vector3<double> position; // Notice it is unsigned! SVertex vertex; /* Need to draw it, so I store position in vertex */ vertex.pos = VEC3TOVEC4(position); // Works, but generates warning about losing information
But I wouldn't be writing this post unless I tackled that little issue, and for once I can add that the solution is quite nice as well.
Vector3<double> position; // Notice it is unsigned! SVertex vertex; /* Need to draw it, so I store position in vertex */ vertex.pos.Set(position.array, 3); // Works, no errors and no warnings vertex.pos = Vector4f(position.array, 3); // Works fine as well
So what did I change?
Well, I used mutliple template (one for the class and for the function/constructor). This looks something like this:
template <typename T> struct Vector4
{
/* ... */
template <typename R>
explicit inline Vector4<T>(const R* values, const unsigned int elements/*=4*/);
template <typename R>
inline Vector4<T>& Set(const R* values, const unsigned int elements/*=4*/);
/* ... */
};
// Implementation
template <typename T> template <typename R>
Vector4<T>::Vector4(const R* values, unsigned int elements)
: x(elements > 0 ? (T)values[0] : 0), y(elements > 1 ? (T)values[1] : 0)
, z(elements > 2 ? (T)values[2] : 0), w(elements > 3 ? (T)values[3] : 0)
{
}
template <typename T> template <typename R>
Vector4<T>& Vector4<T>::Set(const R* values, const unsigned int elements)
{
x = (elements > 0 ? (T)values[0] : 0);
y = (elements > 1 ? (T)values[1] : 0);
z = (elements > 2 ? (T)values[2] : 0);
w = (elements > 3 ? (T)values[3] : 0);
return *this;
}
If you take a look at the code I think it is quite clear except that you might have some questions.
-
Q: Why do you use [cci_cpp]explicit[/cci_cpp] with the constructor?A: Because that prevents the implicit use of constructors. If I would allow it a [cci_cpp]Vector4u[/cci_cpp] could be implicit assigned to [cci_cpp]Vector3f[/cci_cpp], although it would be missing an argument. However I think that when you are converting, you should be somewhat aware of it, especially when it can be expensive.
-
Q: Why have you commented out the default value for [cci_cpp]elements[/cci_cpp]?A: Because you don't know how many elements there are in [cci_cpp]values[/cci_cpp] might be (there is a method to find out).
-
Q: So why don't you find out automatically and what is with those conditionals in the constructor?A: Those two are related. By telling it explicitly there is a real good chance that the compiler removes the conditionals, so the [cci_cpp] ( check ? true-value : false-value) [/cci_cpp] check will be removed.