I want to create a framework - collection of libraries.
Why static libraries? Compiler build them very fast. Easy to use.
Something about code:
All functions, struct and other types must have names with letters 'sl' in the beginning.
Do not use `namespace` in API. Can use it for internal things.
Do not use STL in API. Can use it for internal things.
I will prefer C-style programming (c arrays, c strings)
Use char* strings, not wchar* or other.
Names must looks like this slLongName
Why no namespaces and not_like_this_names? Because this is huge wasting of time. Names_like_this can be used in classes like containers, or in math classes. But not in Interface classes.
I will use Visual Studio. About folders:
`build` - contain project files
`inc` - include files
`libs` - static library files
`src` - source code, including all 3rd party libraries.
I don't want to use things like ref count, or scene manager.
I need to write first layer that will be above base things.
Only after this, I will write second layer, then third layer and others.
Do not write complicated classes for basic things, like for texture.
Write simple class for texture, then write more complex class using this class.
I will put include files and source code in folders, for example, everything for math will be in forlder with name `math`.
All basic functionality will be in base library. Other things will be in other libraries.
There is must be a file, that will include all basic things. It will located in `inc` folder, and will have name - `slowlib.h`
Macros
Preprocessor. In other file, I will put macros, that will help to make code more platform independent. And just useful macros.
// I think this is unnecessary, maybe this is old style thing, but I saw it in many
// professional projects.
// Just...`inline` will not guarantee that function will be inline
#ifdef _MSC_VER
#define SL_FORCEINLINE __forceinline
#else
#define SL_FORCEINLINE inline
#endif
Detect platform
#if defined(WIN32) | defined(_WIN64) | defined(_WIN32)
#define SL_PLATFORM_WINDOWS
#else
#error Please, write code for other platform
#endif
When you use C functions from C library in C++ you need to add this in function definition\declaration. It for Visual Studio.
#ifdef SL_PLATFORM_WINDOWS
#define SL_CDECL _cdecl
#else
#error Please, write code for other platform
#endif
Debug
#ifdef _DEBUG
#define SL_DEBUG
#endif
MAKEFOURCC
// `pack` 4 bytes into 1 uint32_t
// I don't know about speed.
// uint32_i magic = SL_MAKEFOURCC('‰', 'P', 'N', 'G');
// //magic must be `1196314761`
#define SL_MAKEFOURCC( ch0, ch1, ch2, ch3 )\
((uint32_t)(uint8_t)(ch0)|((uint32_t)(uint8_t)(ch1)<<8)|\
((uint32_t)(uint8_t)(ch2)<<16)|((uint32_t)(uint8_t)(ch3)<<24))
Need to know if this is 64 bit configuration
#ifdef SL_PLATFORM_WINDOWS
#if defined _WIN64 || defined __x86_64__
#define SL_BIT_64
#endif
#else
#error Please, write code for other platform
#endif
// For example if you have 0xAABBCCDD
// You can get 0xAABB and 0xCCDD using this macros
#define SL_LO32(l) ((uint16_t)(((uint32_t)(l)) & 0xffff))
#define SL_HI32(l) ((uint16_t)((((uint32_t)(l)) >> 16) & 0xffff))
Memory
Add functions that will allocate and free memory. Memory allocated in one module(exe, dll),
can not be deallocated in other. For example, if you create .dll with function that will get
some text `void libGetInfo(std::string* s){//fill s here}` you will get error, because library
will allocate memory for string data, probably, free old memory, and then in application, app
will free this memory. .exe and .dll can use different system libraries for working with memory.
Better to make your own functions for this.
typedef void* slDLLHandle; // HMODULE in Windows
typedef void* slDLLFunction;
class slDLL
{
public:
// Load dynamic lybrary.
// Return pointer if library is loaded.
// Call free when you no need it.
static slDLLHandle load(const char* libraryName);
// Unload dynamic lybrary.
static void free(slDLLHandle* library);
// Get function from .dll
// Return NULL if there is some error.
static slDLLFunction get_proc(slDLLHandle* library, const char* functionName);
};
In my assert I will use stacktracer. SL_ASSERT will call sl_internal::onAssert().
onAssert() will call default function for assert, you can change it using function slSetOnAssert.
In this project I decided to write unicode string. Not template class.
Unicode string have method for conversion into UTF8 and UTF16. I need to store this text. Create simple classes.
// just data and size
// it will use in slString
class slStringA
{
void reallocate(size_t new_allocated);
public:
slStringA();
~slStringA();
void push_back(char8_t);
size_t m_allocated = 0;
size_t m_size = 0;
char8_t* m_data = nullptr;
};
class slStringW
{
void reallocate(size_t new_allocated);
public:
slStringW();
~slStringW();
void push_back(char16_t);
size_t m_allocated = 0;
size_t m_size = 0;
char16_t* m_data = nullptr;
};
Unicode string. Why I need this? Because C++ method (std::wcsrtombs) is not working.
And I don't wanted to find other solutions. Better to make your own.
Implementation is too long. For more speed I generated utf8 and utf16 codes. It in UnicodeChars.inl
Stacktracer
Stacktracer will tell you programm execution position. Only when you call function.
It usually use in assert. So, you will get more usefull information when you make some mistake.
Last time I tried (some years ago), and it not worked.
class slStackTracer
{
public:
static void Print();
};