SFML community forums

General => General discussions => Topic started by: Relic on October 13, 2010, 05:37:39 am

Title: Using named colors
Post by: Relic on October 13, 2010, 05:37:39 am
Hi guys! This is my 1st post here. I'm working on my game engine that uses sfml. And I want to share portion of my (and betajaen's) code. If it is helpfull may be it is worth to be wikied.:)  
I think that pre-defined named colors are much more convenient than their digital equivalents. In my engine's graphics utility class I'm using the following enum that was borrowed from OGRE's addon Gorilla created by betajaen (license included). Unlike sfml's approach where pre-defined basic colors (Red, Blue etc.) are static objects, I use a convertion function that returns sf::Color. May be this code will be useful for somebody.

 
Code: [Select]
/*
    Gorilla
    -------
   
    Copyright (c) 2010 Robin Southern
                                                                                 
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
                                                                                 
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.
                                                                                 
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
   
*/
namespace NamedColor
{
enum NamedColor
{
  None = 0, // No Color.                                                        
  AliceBlue=0xf0f8ff,      Gainsboro=0xdcdcdc,            MistyRose=0xffe4e1,    
  AntiqueWhite=0xfaebd7,   GhostWhite=0xf8f8ff,           Moccasin=0xffe4b5,      
  Aqua=0x00ffff,           Gold=0xffd700,                 NavajoWhite=0xffdead,  
  Aquamarine=0x7fffd4,     Goldenrod=0xdaa520,            Navy=0x000080,          
  Azure=0xf0ffff,          Gray=0x808080,                 OldLace=0xfdf5e6,      
  Beige=0xf5f5dc,          Green=0x008000,                Olive=0x808000,        
  Bisque=0xffe4c4,         GreenYellow=0xadff2f,          OliveDrab=0x6b8e23,    
  Black=0x000000,          Grey=0x808080,                 Orange=0xffa500,        
  BlanchedAlmond=0xffebcd, Honeydew=0xf0fff0,             OrangeRed=0xff4500,    
  Blue=0x0000ff,           HotPink=0xff69b4,              Orchid=0xda70d6,        
  BlueViolet=0x8a2be2,     IndianRed=0xcd5c5c,            PaleGoldenrod=0xeee8aa,
  Brown=0xa52a2a,          Indigo=0x4b0082,               PaleGreen=0x98fb98,    
  Burlywood=0xdeb887,      Ivory=0xfffff0,                PaleTurquoise=0xafeeee,
  CadetBlue=0x5f9ea0,      Khaki=0xf0e68c,                PaleVioletRed=0xdb7093,
  Chartreuse=0x7fff00,     Lavender=0xe6e6fa,             PapayaWhip=0xffefd5,    
  Chocolate=0xd2691e,      LavenderBlush=0xfff0f5,        PeachPuff=0xffdab9,    
  Coral=0xff7f50,          LawnGreen=0x7cfc00,            Peru=0xcd853f,          
  CornflowerBlue=0x6495ed, LemonChiffon=0xfffacd,         Pink=0xffc0cb,          
  Cornsilk=0xfff8dc,       LightBlue=0xadd8e6,            Plum=0xdda0dd,          
  Crimson=0xdc143c,        LightCoral=0xf08080,           PowderBlue=0xb0e0e6,    
  Cyan=0x00ffff,           LightCyan=0xe0ffff,            Purple=0x800080,        
  DarkBlue=0x00008b,       LightGoldenrodyellow=0xfafad2, Red=0xff0000,          
  DarkCyan=0x008b8b,       LightGray=0xd3d3d3,            RosyBrown=0xbc8f8f,    
  DarkGoldenrod=0xb8860b,  LightGreen=0x90ee90,           RoyalBlue=0x4169e1,    
  DarkGray=0xa9a9a9,       LightGrey=0xd3d3d3,            SaddleBrown=0x8b4513,  
  DarkGreen=0x006400,      LightPink=0xffb6c1,            Salmon=0xfa8072,        
  DarkGrey=0xa9a9a9,       LightSalmon=0xffa07a,          SandyBrown=0xf4a460,    
  DarkKhaki=0xbdb76b,      LightSeagreen=0x20b2aa,        SeaGreen=0x2e8b57,      
  DarkMagenta=0x8b008b,    LightSkyblue=0x87cefa,         SeaShell=0xfff5ee,      
  DarkOlivegreen=0x556b2f, LightSlategray=0x778899,       Sienna=0xa0522d,        
  DarkOrange=0xff8c00,     LightSlategrey=0x778899,       Silver=0xc0c0c0,        
  DarkOrchid=0x9932cc,     LightSteelblue=0xb0c4de,       SkyBlue=0x87ceeb,      
  DarkRed=0x8b0000,        LightYellow=0xffffe0,          SlateBlue=0x6a5acd,    
  DarkSalmon=0xe9967a,     Lime=0x00ff00,                 SlateGray=0x708090,    
  DarkSeagreen=0x8fbc8f,   LimeGreen=0x32cd32,            SlateGrey=0x708090,    
  DarkSlateblue=0x483d8b,  Linen=0xfaf0e6,                Snow=0xfffafa,          
  DarkSlategray=0x2f4f4f,  Magenta=0xff00ff,              SpringGreen=0x00ff7f,  
  DarkSlategrey=0x2f4f4f,  Maroon=0x800000,               SteelBlue=0x4682b4,    
  DarkTurquoise=0x00ced1,  MediumAquamarine=0x66cdaa,     Tan=0xd2b48c,          
  DarkViolet=0x9400d3,     MediumBlue=0x0000cd,           Teal=0x008080,          
  DeepPink=0xff1493,       MediumOrchid=0xba55d3,         Thistle=0xd8bfd8,      
  DeepSkyblue=0x00bfff,    MediumPurple=0x9370db,         Tomato=0xff6347,        
  DimGray=0x696969,        MediumSeaGreen=0x3cb371,       Turquoise=0x40e0d0,    
  DimGrey=0x696969,        MediumSlateBlue=0x7b68ee,      Violet=0xee82ee,        
  DodgerBlue=0x1e90ff,     MediumSpringGreen=0x00fa9a,    Wheat=0xf5deb3,        
  FireBrick=0xb22222,      MediumTurquoise=0x48d1cc,      White=0xffffff,        
  FloralWhite=0xfffaf0,    MediumBioletRed=0xc71585,      WhiteSmoke=0xf5f5f5,    
  ForestGreen=0x228b22,    MidnightBlue=0x191970,         Yellow=0xffff00,        
  Fuchsia=0xff00ff,        MintCream=0xf5fffa,            YellowGreen=0x9acd32    
};
} // namespace

//-----------------------------------------------------------------------------
class GraphUtils
{

public:

  static sf::Color ToSfColor(unsigned int namedColor, unsigned char alpha = 255);
};

Code: [Select]
//-----------------------------------------------------------------------------
sf::Color GraphUtils::ToSfColor(unsigned int namedColor, unsigned char alpha)
{
  union
  {
    unsigned int whole;
    unsigned char byte[4];
  };
 
  whole = namedColor;
 
  return sf::Color(byte[2], byte[1], byte[0], alpha);
};


Using named colors...
Code: [Select]

...
label.SetFrameColor(GraphUtils::ToSfColor(NamedColor::BlueViolet));
...
Title: Using named colors
Post by: Laurent on October 13, 2010, 07:52:55 am
Hi :)

I have two questions:

1. What's the benefit of having constants + a conversions function, instead of the colors directly as sf::Color?

2. Your conversion trick involving a union is not portable (it's broken when endianness is reversed), and it's not even supported by the standard as a conversion method (even if in practice it always works), technically it is an undefined behaviour.
Title: Using named colors
Post by: Silvah on October 13, 2010, 08:30:23 am
Quote from: "Laurent"
1. What's the benefit of having constants + a conversions function, instead of the colors directly as sf::Color?
According to the standard, constants of non-POD types cannot be stored in constant data section, they have to be put into modifiable data section and initialized before main() instead. On the other hand, enumeration values are in the same class as numeric literals, they aren't stored anywhere in the binary at all (that is, they're almost always inlined into instruction stream).
Title: Using named colors
Post by: Laurent on October 13, 2010, 08:40:52 am
Quote
According to the standard, constants of non-POD types cannot be stored in constant data section, they have to be put into modifiable data section and initialized before main() instead. On the other hand, enumeration values are in the same class as numeric literals, they aren't stored anywhere in the binary at all (that is, they're almost always inlined into instruction stream).

Ok you're right, but what's the point? Saving memory? I prefer using slightly more memory (and honestly, how cares about these few bytes?) and a little less CPU at runtime -- and as a side effect, a less verbose syntax for using these colors.
Title: Using named colors
Post by: Relic on October 13, 2010, 09:36:58 am
The reason is simple. I did not want to manually split betajaen's RGB constants in parts and construct sf::Color for each named color, or write a few lines of python code that would do it for me. I'm lazy. :) And sf::Color has no suitable constructor that receives RGB as solid integer. As for performance, yes, the convertion is not too swift. But i don't think it matters, as assigning colors mostly occurs somewhere in initialization code that is executed once. :)
Title: Using named colors
Post by: Laurent on October 13, 2010, 09:46:50 am
Quote
The reason is simple. I did not want to manually split betajaen's RGB constants in parts and construct sf::Color for each named color, or write a fiew lines of python code that would do it for me. I'm lazy.

Maybe it's worth doing the effort, and providing users with a more efficient/clean/simple code ;)

Quote
As for performance, yes, the convertion is not too swift. But i don't think it matters, as assigning colors mostly occurs somewhere in initialization code that is executed once.

Yep, performance doesn't really matter. What's the most important here is that your code doesn't work on big-endian processors (like PPC).

You should use this code instead:
Code: [Select]
sf::Color GraphUtils::ToSfColor(unsigned int namedColor, unsigned char alpha)
{
    sf::Uint8 r = static_cast<sf::Uint8>((namedColor & 0xFF0000) >> 16);
    sf::Uint8 g = static_cast<sf::Uint8>((namedColor & 0x00FF00) >> 8);
    sf::Uint8 b = static_cast<sf::Uint8>(namedColor & 0x0000FF);

    return sf::Color(r, g, b, alpha);
};
Title: Using named colors
Post by: Relic on October 13, 2010, 10:04:54 am
Quote
your code doesn't work on big-endian processors (like PPC)

Agreed... I'm just sitting on PC all the time.
Title: Using named colors
Post by: Silvah on October 13, 2010, 11:12:42 am
Quote from: "Laurent"
Ok you're right, but what's the point? Saving memory? I prefer using slightly more memory (and honestly, how cares about these few bytes?) and a little less CPU at runtime -- and as a side effect, a less verbose syntax for using these colors.
Unless your compiler is extremely bad at inlining (or is simply unable to inline) and constant propagation, you're saving both memory and CPU (program will start slightly faster, because it won't have to initialize all these "constants" at startup).
Title: Using named colors
Post by: Laurent on October 13, 2010, 11:33:16 am
We shouldn't focus on such unnoticeable things... The only important thing here is how this code is going to be used by people. And as a user, I would prefer using direct colors than constants + a conversion function every time I need them. There's no need for the constants alone, one always need to use them together with the conversion function. So why not providing the result directly?
Title: Using named colors
Post by: Relic on October 13, 2010, 12:51:37 pm
Ok, I'll make an include file with the code similar to following
Code: [Select]
#include <SFML/Color.hpp>

namespace NamedColor
{
static const sf::Color AliceBlue(0xF0, 0xF8, 0xFF);
static const sf::Color AntiqueWhite(0xFA, 0xEB, 0xD7);
// more constants
...
} // namespace

The constants still sit in the namespace NamedColor. It can be changed. As sfml is opensource everyone can even move them inside class sf::Color and extend the existing list of pre-defined color constants.
Title: Using named colors
Post by: Nexus on October 13, 2010, 06:06:34 pm
I have to agree with Laurent: To call a conversion function every time you need a sf::Color is an unnecessary burden resulting from questionable considerations.

The performance "arguments" brought here are typical for premature optimization. Load a single sf::Image, and the runtime and memory usage outweigh by huge factors. If we talked about time-critical code at the inside of an often-called loop and the big optimization opportunities have already been exploited, okay. But saving a few bytes and a few cycles once at initialization (which is hardly noticeable) at the cost of making code user-unfriendly is generally a bad idea.

About the laziness to convert every literal: It's no big deal to write a program that replaces AliceBlue=0xf0f8ff, with sf::Color AliceBlue(0xf0, 0xf8, 0xff);. Automated replacement is far less error-prone than manual one.

And just that you're aware, Relic: By using the static storage class (or no explicit keyword at const variables), the memory gets duplicated for each translation unit. The storage class extern avoids that, but then the definitions have to be moved to an implementation file.
Title: Using named colors
Post by: Silvah on October 13, 2010, 08:06:11 pm
Quote from: "Laurent"
We shouldn't focus on such unnoticeable things... The only important thing here is how this code is going to be used by people.
Ah, it's no wonder that I have to wait thirty seconds before my internet browser starts. :P

Quote from: "Nexus"
The performance "arguments" brought here are typical for premature optimization.
Yeah, premature optimization is by all means bad. What about premature pessimization? ;) Yes,
I know, PCs have several gigs of RAM and CPUs that can do zillions
of operations per second today. Maybe I was programming for machines with severly limited resources too long?

I've posted here a solution which didn't require explicit conversion and global constructors, nor it required more memory than sf::Color constants, and was also pretty efficient at runtime, at the cost of being somewhat hackish, but I deleted it, heh...
Title: Using named colors
Post by: Nexus on October 13, 2010, 11:08:19 pm
Quote from: "Silvah"
Yeah, premature optimization is by all means bad. What about premature pessimization? ;)
It's as bad. But I want to explain you why we're not talking about it in this topic.

Premature pessimization means not to think about efficiency where it is appropriate. It's like using the wrong container or algorithm, creating unnecessary copies, allocating too much memory, etc. Given the right knowledge, such mistakes can be easily avoided, while the alternative implies a similar implementation effort.

In contrast, premature optimization means to waste time at optimizing program parts that are not of time-critical relevance. Often, it goes hand in hand with the avoidance of profilers and measurement, the reliance on pure assumptions (which are not rarely wrong), and a neglect of the real bottlenecks. Premature optimization is especially evil as it often includes complex, hardly readable and non-portable code (in short: dirty hacks) and as it approves user-unfriendliness and error-proneness. The price to pay is far too high, being mindful of the fact that the effective performance gain is neither proven nor relevant. As you see, the thread and your alternative suggestion fit many of the just mentioned criterions.
Title: Using named colors
Post by: Silvah on October 13, 2010, 11:59:21 pm
Well, the things you're talking about are pretty obvious. I do know what premature optimization and pessimization are.

Quote from: "Nexus"
It's as bad. But I want to explain you why we're not talking about it in this topic.
We do. I really don't want the browser to take thirty second to load (I'll use that analogy, until I'll find a better one) just because its developers love non-trivial global objects.

Honestly, I don't see any reason to argue about that code. It's unlikely that it will be incorporated into SFML, after all. It's unlikely that you or I will meet it anywhere in production. It's unlikely that... you got the idea.

By the way - I was once told to avoid global constructors altogether by all possible means, maybe I still subconsciously try to adhere to this rule, hehe ;)
Title: Using named colors
Post by: Nexus on October 14, 2010, 06:38:17 am
Quote from: "Silvah"
We do. I really don't want the browser to take thirty second to load (I'll use that analogy, until I'll find a better one) just because its developers love non-trivial global objects.
What kind of argument is this?
"My browser starts slowly" => "The reason must be the construction of global objects" => "So I don't construct constants and use bad code instead"

Sorry, but you can't draw that conclusion. You don't know why the browser starts slowly. You don't know either how long the construction takes and how relevant it really is, because you have never measured it. You are just guessing.

Quote from: "Silvah"
Honestly, I don't see any reason to argue about that code.
It's just bad style to evoke undefined behaviour (union-cast) because of a non-existing problem.

Quote from: "Silvah"
By the way - I was once told to avoid global constructors altogether by all possible means, maybe I still subconsciously try to adhere to this rule, hehe ;)
The one who told you that probably meant constructions of depending modules shouldn't happen at global level since the initialization order is undefined.
Title: Using named colors
Post by: Silvah on October 14, 2010, 11:41:16 am
Quote from: "Nexus"
"So I don't construct constants and use bad code instead"
Can you explain me why creating objects at local scope and only when they're really needed is considered "bad code"?

I'm not talking now about the problem in this thread, but rather about its generalization. Why
Code: [Select]
void SomeClass::foo()
{
  // we don't need this constant anywhere except in this function
  const Something blah(888);
  // ... some code ...
}
is worse than
Code: [Select]
// literally hundreds of non-trivial global constants omitted
void SomeClass::foo()
{
  // ... some code ...
}
? I always thought the opposite is true.

Quote from: "Nexus"
You don't know why the browser starts slowly. You don't know either how long the construction takes and how relevant it really is, because you have never measured it. You are just guessing.
Uhm, okay, you got me this time. I don't even want to know why that browser starts so slowly, it's simplier to switch to a different one.

But I know why one of programs that I was working on was starting slowly. Unless the profiler was just a random number generator in disguise, the global constructors (and stupid fellow programmers - how stupid one has to be to perform a lot of I/O in a constructor of global object (moreover, it was a constant!) and to make just about everything global?) were guilt.

Quote from: "Nexus"
It's just bad style to evoke undefined behaviour (union-cast) because of a non-existing problem.
As Laurent showed us, it's perfectly possible to get rid of union cast in this case.

Quote from: "Nexus"
The one who told you that probably meant constructions of depending modules shouldn't happen at global level since the initialization order is undefined.
The real reason was that sometimes they were not called, since the runtime never supported them properly.
Title: Using named colors
Post by: Relic on October 14, 2010, 01:01:52 pm
Finally I created a structure containing static constants. From now on I'm using it and quite happy.  :)  For those who want the constants here are the code. For portability /#pragma once/ should be replaced with an include guard.

header:

Code: [Select]
#pragma once

#include <SFML/Graphics/Color.hpp>

namespace Named
{

//-----------------------------------------------------------------------------
struct Color
{
    static const sf::Color AliceBlue;
    static const sf::Color AntiqueWhite;
    static const sf::Color Aqua;          
    static const sf::Color Aquamarine;    
    static const sf::Color Azure;          
    static const sf::Color Beige;          
    static const sf::Color Bisque;        
    static const sf::Color Black;          
    static const sf::Color BlanchedAlmond;
    static const sf::Color Blue;          
    static const sf::Color BlueViolet;    
    static const sf::Color Brown;          
    static const sf::Color Burlywood;      
    static const sf::Color CadetBlue;      
    static const sf::Color Chartreuse;    
    static const sf::Color Chocolate;      
    static const sf::Color Coral;          
    static const sf::Color CornflowerBlue;
    static const sf::Color Cornsilk;      
    static const sf::Color Crimson;        
    static const sf::Color Cyan;          
    static const sf::Color DarkBlue;      
    static const sf::Color DarkCyan;      
    static const sf::Color DarkGoldenrod;  
    static const sf::Color DarkGray;      
    static const sf::Color DarkGreen;      
    static const sf::Color DarkKhaki;      
    static const sf::Color DarkMagenta;    
    static const sf::Color DarkOlivegreen;
    static const sf::Color DarkOrange;    
    static const sf::Color DarkOrchid;    
    static const sf::Color DarkRed;        
    static const sf::Color DarkSalmon;    
    static const sf::Color DarkSeagreen;  
    static const sf::Color DarkSlateblue;  
    static const sf::Color DarkSlategray;  
    static const sf::Color DarkTurquoise;  
    static const sf::Color DarkViolet;    
    static const sf::Color DeepPink;      
    static const sf::Color DeepSkyblue;    
    static const sf::Color DimGray;        
    static const sf::Color DodgerBlue;    
    static const sf::Color FireBrick;      
    static const sf::Color FloralWhite;    
    static const sf::Color ForestGreen;    
    static const sf::Color Fuchsia;
    static const sf::Color Gainsboro;            
    static const sf::Color GhostWhite;          
    static const sf::Color Gold;                
    static const sf::Color Goldenrod;            
    static const sf::Color Gray;                
    static const sf::Color Green;                
    static const sf::Color GreenYellow;          
    static const sf::Color Honeydew;            
    static const sf::Color HotPink;              
    static const sf::Color IndianRed;            
    static const sf::Color Indigo;              
    static const sf::Color Ivory;                
    static const sf::Color Khaki;                
    static const sf::Color Lavender;            
    static const sf::Color LavenderBlush;        
    static const sf::Color LawnGreen;            
    static const sf::Color LemonChiffon;        
    static const sf::Color LightBlue;            
    static const sf::Color LightCoral;          
    static const sf::Color LightCyan;            
    static const sf::Color LightGoldenrodyellow;
    static const sf::Color LightGray;            
    static const sf::Color LightGreen;          
    static const sf::Color LightPink;            
    static const sf::Color LightSalmon;          
    static const sf::Color LightSeagreen;        
    static const sf::Color LightSkyblue;        
    static const sf::Color LightSlategray;      
    static const sf::Color LightSteelblue;      
    static const sf::Color LightYellow;          
    static const sf::Color Lime;                
    static const sf::Color LimeGreen;            
    static const sf::Color Linen;                
    static const sf::Color Magenta;              
    static const sf::Color Maroon;              
    static const sf::Color MediumAquamarine;    
    static const sf::Color MediumBlue;          
    static const sf::Color MediumOrchid;        
    static const sf::Color MediumPurple;        
    static const sf::Color MediumSeaGreen;      
    static const sf::Color MediumSlateBlue;      
    static const sf::Color MediumSpringGreen;    
    static const sf::Color MediumTurquoise;      
    static const sf::Color MediumBioletRed;      
    static const sf::Color MidnightBlue;        
    static const sf::Color MintCream;
    static const sf::Color MistyRose;    
    static const sf::Color Moccasin;      
    static const sf::Color NavajoWhite;  
    static const sf::Color Navy;          
    static const sf::Color OldLace;      
    static const sf::Color Olive;        
    static const sf::Color OliveDrab;    
    static const sf::Color Orange;        
    static const sf::Color OrangeRed;    
    static const sf::Color Orchid;        
    static const sf::Color PaleGoldenrod;
    static const sf::Color PaleGreen;    
    static const sf::Color PaleTurquoise;
    static const sf::Color PaleVioletRed;
    static const sf::Color PapayaWhip;    
    static const sf::Color PeachPuff;    
    static const sf::Color Peru;          
    static const sf::Color Pink;          
    static const sf::Color Plum;          
    static const sf::Color PowderBlue;    
    static const sf::Color Purple;        
    static const sf::Color Red;          
    static const sf::Color RosyBrown;    
    static const sf::Color RoyalBlue;    
    static const sf::Color SaddleBrown;  
    static const sf::Color Salmon;        
    static const sf::Color SandyBrown;    
    static const sf::Color SeaGreen;      
    static const sf::Color SeaShell;      
    static const sf::Color Sienna;        
    static const sf::Color Silver;        
    static const sf::Color SkyBlue;      
    static const sf::Color SlateBlue;    
    static const sf::Color SlateGray;    
    static const sf::Color Snow;          
    static const sf::Color SpringGreen;  
    static const sf::Color SteelBlue;    
    static const sf::Color Tan;          
    static const sf::Color Teal;          
    static const sf::Color Thistle;      
    static const sf::Color Tomato;        
    static const sf::Color Turquoise;    
    static const sf::Color Violet;        
    static const sf::Color Wheat;        
    static const sf::Color White;        
    static const sf::Color WhiteSmoke;    
    static const sf::Color Yellow;        
    static const sf::Color YellowGreen;    
};

} // namespace Named


implementation:

Code: [Select]
namespace Named
{

    const sf::Color Color::AliceBlue(0xF0, 0xF8, 0xFF);
    const sf::Color Color::AntiqueWhite(0xFA, 0xEB, 0xD7);
    const sf::Color Color::Aqua(0x00, 0xFF, 0xFF);
    const sf::Color Color::Aquamarine(0x7F, 0xFF, 0xD4);
    const sf::Color Color::Azure(0xF0, 0xFF, 0xFF);
    const sf::Color Color::Beige(0xF5, 0xF5, 0xDC);    
    const sf::Color Color::Bisque(0xFF, 0xE4, 0xC4);
    const sf::Color Color::Black(0x00, 0x00, 0x00);
    const sf::Color Color::BlanchedAlmond(0xFF, 0xEB, 0xCD);
    const sf::Color Color::Blue(0x00, 0x00, 0xFF);
    const sf::Color Color::BlueViolet(0x8A, 0x2B, 0xE2);
    const sf::Color Color::Brown(0xA5, 0x2A, 0x2A);    
    const sf::Color Color::Burlywood(0xDE, 0xB8, 0x87);
    const sf::Color Color::CadetBlue(0x5F, 0x9E, 0xA0);
    const sf::Color Color::Chartreuse(0x7F, 0xFF, 0x00);
    const sf::Color Color::Chocolate(0xD2, 0x69, 0x1E);
    const sf::Color Color::Coral(0xFF, 0x7F, 0x50);
    const sf::Color Color::CornflowerBlue(0x64, 0x95, 0xED);
    const sf::Color Color::Cornsilk(0xFF, 0xF8, 0xDC);
    const sf::Color Color::Crimson(0xDC, 0x14, 0x3C);
    const sf::Color Color::Cyan(0x00, 0xFF, 0xFF);
    const sf::Color Color::DarkBlue(0x00, 0x00, 0x8B);
    const sf::Color Color::DarkCyan(0x00, 0x8B, 0x8B);
    const sf::Color Color::DarkGoldenrod(0xB8, 0x86, 0x0B);
    const sf::Color Color::DarkGray(0xA9, 0xA9, 0xA9);
    const sf::Color Color::DarkGreen(0x00, 0x64, 0x00);
    const sf::Color Color::DarkKhaki(0xBD, 0xB7, 0x6B);
    const sf::Color Color::DarkMagenta(0x8B, 0x00, 0x8B);
    const sf::Color Color::DarkOlivegreen(0x55, 0x6B, 0x2F);
    const sf::Color Color::DarkOrange(0xFF, 0x8C, 0x00);
    const sf::Color Color::DarkOrchid(0x99, 0x32, 0xCC);
    const sf::Color Color::DarkRed(0x8B, 0x00, 0x00);
    const sf::Color Color::DarkSalmon(0xE9, 0x96, 0x7A);
    const sf::Color Color::DarkSeagreen(0x8F, 0xBC, 0x8F);
    const sf::Color Color::DarkSlateblue(0x48, 0x3D, 0x8B);
    const sf::Color Color::DarkSlategray(0x2F, 0x4F, 0x4F);
    const sf::Color Color::DarkTurquoise(0x00, 0xCE, 0xD1);
    const sf::Color Color::DarkViolet(0x94, 0x00, 0xD3);
    const sf::Color Color::DeepPink(0xFF, 0x14, 0x93);
    const sf::Color Color::DeepSkyblue(0x00, 0xBF, 0xFF);
    const sf::Color Color::DimGray(0x69, 0x69, 0x69);
    const sf::Color Color::DodgerBlue(0x1E, 0x90, 0xFF);
    const sf::Color Color::FireBrick(0xB2, 0x22, 0x22);
    const sf::Color Color::FloralWhite(0xFF, 0xFA, 0xF0);
    const sf::Color Color::ForestGreen(0x22, 0x8B, 0x22);
    const sf::Color Color::Fuchsia(0xFF, 0x00, 0xFF);
    const sf::Color Color::Gainsboro(0xDC, 0xDC, 0xDC);
    const sf::Color Color::GhostWhite(0xF8, 0xF8, 0xFF);
    const sf::Color Color::Gold(0xFF, 0xD7, 0x00);
    const sf::Color Color::Goldenrod(0xDA, 0xA5, 0x20);
    const sf::Color Color::Gray(0x80, 0x80, 0x80);
    const sf::Color Color::Green(0x00, 0x80, 0x00);
    const sf::Color Color::GreenYellow(0xAD, 0xFF, 0x2F);
    const sf::Color Color::Honeydew(0xF0, 0xFF, 0xF0);
    const sf::Color Color::HotPink(0xFF, 0x69, 0xB4);
    const sf::Color Color::IndianRed(0xCD, 0x5C, 0x5C);
    const sf::Color Color::Indigo(0x4B, 0x00, 0x82);
    const sf::Color Color::Ivory(0xFF, 0xFF, 0xF0);
    const sf::Color Color::Khaki(0xF0, 0xE6, 0x8C);
    const sf::Color Color::Lavender(0xE6, 0xE6, 0xFA);
    const sf::Color Color::LavenderBlush(0xFF, 0xF0, 0xF5);
    const sf::Color Color::LawnGreen(0x7C, 0xFC, 0x00);
    const sf::Color Color::LemonChiffon(0xFF, 0xFA, 0xCD);
    const sf::Color Color::LightBlue(0xAD, 0xD8, 0xE6);
    const sf::Color Color::LightCoral(0xF0, 0x80, 0x80);
    const sf::Color Color::LightCyan(0xE0, 0xFF, 0xFF);
    const sf::Color Color::LightGoldenrodyellow(0xFA, 0xFA, 0xD2);
    const sf::Color Color::LightGray(0xD3, 0xD3, 0xD3);
    const sf::Color Color::LightGreen(0x90, 0xEE, 0x90);
    const sf::Color Color::LightPink(0xFF, 0xB6, 0xC1);
    const sf::Color Color::LightSalmon(0xFF, 0xA0, 0x7A);
    const sf::Color Color::LightSeagreen(0x20, 0xB2, 0xAA);
    const sf::Color Color::LightSkyblue(0x87, 0xCE, 0xFA);
    const sf::Color Color::LightSlategray(0x77, 0x88, 0x99);
    const sf::Color Color::LightSteelblue(0xB0, 0xC4, 0xDE);
    const sf::Color Color::LightYellow(0xFF, 0xFF, 0xE0);
    const sf::Color Color::Lime(0x00, 0xFF, 0x00);
    const sf::Color Color::LimeGreen(0x32, 0xCD, 0x32);
    const sf::Color Color::Linen(0xFA, 0xF0, 0xE6);
    const sf::Color Color::Magenta(0xFF, 0x00, 0xFF);
    const sf::Color Color::Maroon(0x80, 0x00, 0x00);
    const sf::Color Color::MediumAquamarine(0x66, 0xCD, 0xAA);
    const sf::Color Color::MediumBlue(0x00, 0x00, 0xCD);
    const sf::Color Color::MediumOrchid(0xBA, 0x55, 0xD3);
    const sf::Color Color::MediumPurple(0x93, 0x70, 0xDB);
    const sf::Color Color::MediumSeaGreen(0x3C, 0xB3, 0x71);
    const sf::Color Color::MediumSlateBlue(0x7B, 0x68, 0xEE);
    const sf::Color Color::MediumSpringGreen(0x00, 0xFA, 0x9A);
    const sf::Color Color::MediumTurquoise(0x48, 0xD1, 0xCC);
    const sf::Color Color::MediumBioletRed(0xC7, 0x15, 0x85);
    const sf::Color Color::MidnightBlue(0x19, 0x19, 0x70);
    const sf::Color Color::MintCream(0xF5, 0xFF, 0xFA);
    const sf::Color Color::MistyRose(0xFF, 0xE4, 0xE1);
    const sf::Color Color::Moccasin(0xFF, 0xE4, 0xB5);
    const sf::Color Color::NavajoWhite(0xFF, 0xDE, 0xAD);
    const sf::Color Color::Navy(0x00, 0x00, 0x80);
    const sf::Color Color::OldLace(0xFD, 0xF5, 0xE6);
    const sf::Color Color::Olive(0x80, 0x80, 0x00);
    const sf::Color Color::OliveDrab(0x6B, 0x8E, 0x23);
    const sf::Color Color::Orange(0xFF, 0xA5, 0x00);
    const sf::Color Color::OrangeRed(0xFF, 0x45, 0x00);
    const sf::Color Color::Orchid(0xDA, 0x70, 0xD6);
    const sf::Color Color::PaleGoldenrod(0xEE, 0xE8, 0xAA);
    const sf::Color Color::PaleGreen(0x98, 0xFB, 0x98);
    const sf::Color Color::PaleTurquoise(0xAF, 0xEE, 0xEE);
    const sf::Color Color::PaleVioletRed(0xDB, 0x70, 0x93);
    const sf::Color Color::PapayaWhip(0xFF, 0xEF, 0xD5);
    const sf::Color Color::PeachPuff(0xFF, 0xDA, 0xB9);
    const sf::Color Color::Peru(0xCD, 0x85, 0x3F);
    const sf::Color Color::Pink(0xFF, 0xC0, 0xCB);
    const sf::Color Color::Plum(0xDD, 0xA0, 0xDD);
    const sf::Color Color::PowderBlue(0xB0, 0xE0, 0xE6);
    const sf::Color Color::Purple(0x80, 0x00, 0x80);
    const sf::Color Color::Red(0xFF, 0x00, 0x00);
    const sf::Color Color::RosyBrown(0xBC, 0x8F, 0x8F);
    const sf::Color Color::RoyalBlue(0x41, 0x69, 0xE1);
    const sf::Color Color::SaddleBrown(0x8B, 0x45, 0x13);
    const sf::Color Color::Salmon(0xFA, 0x80, 0x72);
    const sf::Color Color::SandyBrown(0xF4, 0xA4, 0x60);
    const sf::Color Color::SeaGreen(0x2E, 0x8B, 0x57);
    const sf::Color Color::SeaShell(0xFF, 0xF5, 0xEE);
    const sf::Color Color::Sienna(0xA0, 0x52, 0x2D);
    const sf::Color Color::Silver(0xC0, 0xC0, 0xC0);
    const sf::Color Color::SkyBlue(0x87, 0xCE, 0xEB);
    const sf::Color Color::SlateBlue(0x6A, 0x5A, 0xCD);
    const sf::Color Color::SlateGray(0x70, 0x80, 0x90);
    const sf::Color Color::Snow(0xFF, 0xFA, 0xFA);
    const sf::Color Color::SpringGreen(0x00, 0xFF, 0x7F);
    const sf::Color Color::SteelBlue(0x46, 0x82, 0xB4);
    const sf::Color Color::Tan(0xD2, 0xB4, 0x8C);
    const sf::Color Color::Teal(0x00, 0x80, 0x80);
    const sf::Color Color::Thistle(0xD8, 0xBF, 0xD8);
    const sf::Color Color::Tomato(0xFF, 0x63, 0x47);
    const sf::Color Color::Turquoise(0x40, 0xE0, 0xD0);
    const sf::Color Color::Violet(0xEE, 0x82, 0xEE);
    const sf::Color Color::Wheat(0xF5, 0xDE, 0xB3);
    const sf::Color Color::White(0xFF, 0xFF, 0xFF);
    const sf::Color Color::WhiteSmoke(0xF5, 0xF5, 0xF5);
    const sf::Color Color::Yellow(0xFF, 0xFF, 0x00);
    const sf::Color Color::YellowGreen(0x9A, 0xCD, 0x32);

} // namespace Named


using:

Code: [Select]
   label.SetTextColor(Named::Color::Beige);
    label.SetFrameColor(Named::Color::Crimson);


Who likes functions can get rid of union convertion and use the function and enum from my initial post. Others can use the structure. Who does not care, can forget about this topic at all.     :)
Title: Using named colors
Post by: panithadrum on October 14, 2010, 01:17:09 pm
Now it looks neat :-)
Title: Using named colors
Post by: Nexus on October 14, 2010, 05:25:03 pm
Quote from: "Silvah"
I always thought the opposite is true.
You are right, keeping things local is good practice. The "bad code" referred to the undefined behaviour (using union) and higher code complexity.

Quote from: "Silvah"
As Laurent showed us, it's perfectly possible to get rid of union cast in this case.
Yes, but then your main argument concerning the additional speed doesn't apply anymore.

Quote from: "Silvah"
But I know why one of programs that I was working on was starting slowly. Unless the profiler was just a random number generator in disguise, the global constructors (and stupid fellow programmers - how stupid one has to be to perform a lot of I/O in a constructor of global object (moreover, it was a constant!) and to make just about everything global?) were guilt.
[...]
The real reason was that sometimes they were not called, since the runtime never supported them properly.
Okay, but lets be honest. ;)
In these examples, the problem is definitely not comparable to the optimization approach in this thread. It's an interesting anectode anyway. :)

Quote from: "Relic"
Finally I created a structure containing static constants.
Why do you take a struct instead of a namespace? I don't think you ever want to instanciate it. And why do you prefer Named::Color::ActualColor over NamedColor::ActualColor?
Title: Using named colors
Post by: Silvah on October 14, 2010, 06:24:17 pm
Quote from: "Nexus"
Yes, but then your main argument concerning the additional speed doesn't apply anymore.
Neither it applied to the original OP's code. Or it did and still does - it depends upon whether we're talking about startup speed or the "proper" runtime speed.

Quote from: "Nexus"
In these examples, the problem is definitely not comparable to the optimization approach in this thread.
Yeah, more than thousand movs and more than a hundred of call/ret pairs (that's what OP's code with constants boils down to) are definitely not comparable with doing I/O before main. ;)


Tiny question to Laurent: why constructors of sf::Color are not inline?
Title: Using named colors
Post by: Laurent on October 14, 2010, 06:32:14 pm
Quote
why constructors of sf::Color are not inline?

Because I never inline member functions by default. I do when profilers or users experiences prove that it is really necessary. My rule is "write clean code first, then optimize if necessary" -- yes, I find that putting implementation details in a header is not clean ;)
Title: Using named colors
Post by: Relic on October 15, 2010, 05:20:26 am
Quote
Why do you take a struct instead of a namespace?

I'm gonna add some methods to it later.