Zerosquare (./1318) :C'est aussi géré par le noyau Linux comme un des algorithmes de compression en temps réel.
Pour ceux qui codent sur des vieilles machines (et je sais qu'il y en a ici !), ce truc peut être intéressant :
http://cyan4973.github.io/lz4/
C'est un algorithme de compression avec un ratio correct, et surtout une décompression simple et extrêmement rapide. Il y a déjà des versions en assembleur pour certaines archis
https://en.wikipedia.org/wiki/LZ4_(compression_algorithm) :(gzip qui a déjà un facteur de compression absolument minable.) C'est bien l'énorme défaut de ces algorithmes rapides, ils obtiennent tous des facteurs de compression exécrables par rapport à un compresseur sérieux comme XZ (LZMA2). (Et on peut décompresser du LZMA même sur un 68k à 10-12 MHz.)
The algorithm gives a slightly worse compression ratio than the LZO algorithm – which in turn is worse than algorithms like gzip.
Kevin Kofler (./1322) :Ouais enfin c'est pas la question, on peut décompresser n'importe quel format sur n'importe quelle machine de Turing, si on est suffisamment patient. Et une TI est encore loin d'être le "pire" système embarqué en matière de puissance CPU. L'intérêt est que c'est simple, très rapide et que ça donne un taux de compression non négligeable ; ça n'est pas dans la même catégorie que les algos qui cherchent à avoir le meilleur taux de compression.
on peut décompresser du LZMA même sur un 68k à 10-12 MHz.
It also has state of the art results
At least 32GB of RAM is recommended to run cmix.
enwik9 1000000000 123930173 344244.32 30311032 (soit 1Go de données compressés en 4 jours !!!!).
Compression and decompression time are symmetric
Zerosquare (./1324) :En théorie oui, mais en pratique, la RAM est aussi un facteur limitant. LZMA peut décompresser avec très peu de RAM si le fichier et le dictionnaire sont suffisamment petits.
Ouais enfin c'est pas la question, on peut décompresser n'importe quel format sur n'importe quelle machine de Turing, si on est suffisamment patient.
// Create the button texture (transparent) and set it as render target
m_Texture = SDL_CreateTexture(Game::get()->renderer(), px, SDL_TEXTUREACCESS_TARGET, width, height);
if (m_Texture == nullptr)
{
throw Exception(ERROR_SDL_STR);
}
if (SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_BLEND) != 0)
{
cleanup();
throw Exception(ERROR_SDL_STR);
}
if (SDL_SetRenderDrawColor(Game::get()->renderer(), 0, 0, 0, 0) != 0)
{
cleanup();
throw Exception(ERROR_SDL_STR);
}
if (SDL_RenderClear(Game::get()->renderer()) != 0)
{
cleanup();
throw Exception(ERROR_SDL_STR);
}
if (SDL_SetRenderTarget(Game::get()->renderer(), m_Texture) != 0)
{
cleanup();
throw Exception(ERROR_SDL_STR);
}
Comme vous le voyez, on a 5 lignes de code utiles pour une vingtaine de lignes de vérification. Au début, ça va, puis ça facilite bien le débogage. Mais à un moment ça devient pénible à lire (sans parler du fait que ce n'est pas beau ).bool fonction1(void)
{
// Create the button texture (transparent) and set it as render target
m_Texture = SDL_CreateTexture(Game::get()->renderer(), px, SDL_TEXTUREACCESS_TARGET, width, height);
if (m_Texture == nullptr) return false;
if (SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_BLEND) != 0) return false;
if (SDL_SetRenderDrawColor(Game::get()->renderer(), 0, 0, 0, 0) != 0) return false;
if (SDL_RenderClear(Game::get()->renderer()) != 0) return false;
if (SDL_SetRenderTarget(Game::get()->renderer(), m_Texture) != 0) return false;
return true;
}
void function2(void)
{
if (!fonction1)
{
cleanup();
throw Exception(ERROR_SDL_STR);
}
}
Le principe est du C pur (et n'est pas Ximoon-compliant ), tu dois pouvoir faire ça plus élégamment en C++ avec des exceptions, mais comme c'est pas mon domaine je laisse quelqu'un d'autre proposer une meilleure solution // Create the button texture (transparent) and set it as render target
m_Texture = SDL_CreateTexture(Game::get()->renderer(), px, SDL_TEXTUREACCESS_TARGET, width, height);
if (m_Texture == nullptr)
throw Exception(ERROR_SDL_STR);
if (SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_BLEND) != 0
|| SDL_SetRenderDrawColor(Game::get()->renderer(), 0, 0, 0, 0) != 0
|| SDL_RenderClear(Game::get()->renderer()) != 0
|| SDL_SetRenderTarget(Game::get()->renderer(), m_Texture) != 0)
{
cleanup();
throw Exception(ERROR_SDL_STR);
}
void myassert(int i) : throws Exception { if ( i != 0 ) { cleanup(); throw Exception(ERROR_SDL_STR); } } myassert(SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_BLEND)) ; myassert(SDL_SetRenderDrawColor(Game::get()->renderer(), 0, 0, 0, 0)) ; myassert(SDL_RenderClear(Game::get()->renderer())) ; myassert(SDL_SetRenderTarget(Game::get()->renderer(), m_Texture)) ;(Tu peux d'ailleurs utiliser un mécanisme d'assertion déjà défini, potentiellement en debug uniquement (définition via des macros)
bool fonction1(void)
{
bool ret = false;
// Create the button texture (transparent) and set it as render target
m_Texture = SDL_CreateTexture(Game::get()->renderer(), px, SDL_TEXTUREACCESS_TARGET, width, height);
if (m_Texture == nullptr) goto exit;
if (SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_BLEND) != 0) goto exit;
if (SDL_SetRenderDrawColor(Game::get()->renderer(), 0, 0, 0, 0) != 0) goto exit;
if (SDL_RenderClear(Game::get()->renderer()) != 0) goto exit;
if (SDL_SetRenderTarget(Game::get()->renderer(), m_Texture) != 0) goto exit;
ret = true;
exit:
return ret;
}
Uther (./1340) :Ça peut aider quand il y a de l'analyse automatique de code, me semble-t-il
Perso, je trouve que le grand dogme du "return unique" n'apporte rien, particulièrement si on fait des goto pour y arriver. Au final ça revient exactement à la même chose.
Folco (./1329) :Personnellement, je mettrais:
Voici un bout de mon code du moment :// Create the button texture (transparent) and set it as render target m_Texture = SDL_CreateTexture(Game::get()->renderer(), px, SDL_TEXTUREACCESS_TARGET, width, height); if (m_Texture == nullptr) { throw Exception(ERROR_SDL_STR); } if (SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_BLEND) != 0) { cleanup(); throw Exception(ERROR_SDL_STR); } if (SDL_SetRenderDrawColor(Game::get()->renderer(), 0, 0, 0, 0) != 0) { cleanup(); throw Exception(ERROR_SDL_STR); } if (SDL_RenderClear(Game::get()->renderer()) != 0) { cleanup(); throw Exception(ERROR_SDL_STR); } if (SDL_SetRenderTarget(Game::get()->renderer(), m_Texture) != 0) { cleanup(); throw Exception(ERROR_SDL_STR); }
Comme vous le voyez, on a 5 lignes de code utiles pour une vingtaine de lignes de vérification. Au début, ça va, puis ça facilite bien le débogage. Mais à un moment ça devient pénible à lire (sans parler du fait que ce n'est pas beau ).Comment s'y prendre pour alléger les choses ?
// Create the button texture (transparent) and set it as render target
m_Texture = SDL_CreateTexture(Game::get()->renderer(), px, SDL_TEXTUREACCESS_TARGET, width, height);
if (m_Texture == nullptr) throw Exception(ERROR_SDL_STR);
if (SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_BLEND) != 0)
{
error:
cleanup();
throw Exception(ERROR_SDL_STR);
}
if (SDL_SetRenderDrawColor(Game::get()->renderer(), 0, 0, 0, 0) != 0) goto error;
if (SDL_RenderClear(Game::get()->renderer()) != 0) goto error;
if (SDL_SetRenderTarget(Game::get()->renderer(), m_Texture) != 0) goto error;
voire: // Create the button texture (transparent) and set it as render target
m_Texture = SDL_CreateTexture(Game::get()->renderer(), px, SDL_TEXTUREACCESS_TARGET, width, height);
if (m_Texture == nullptr) {
throw_exception:
throw Exception(ERROR_SDL_STR);
}
if (SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_BLEND) != 0) {
error:
cleanup();
goto throw_exception;
}
if (SDL_SetRenderDrawColor(Game::get()->renderer(), 0, 0, 0, 0) != 0) goto error;
if (SDL_RenderClear(Game::get()->renderer()) != 0) goto error;
if (SDL_SetRenderTarget(Game::get()->renderer(), m_Texture) != 0) goto error;
Zerosquare (./1330) :Bah, c'est un cas classique pour un try … finally. Le mot-clé finally n'existe pas en C++, mais peut-être facilement émulé par une macro. (Seul inconvénient: il faut utiliser des parenthèses en guise d'accolades, parce que la macro doit dupliquer le code à l'intérieur de l'accolade.) Donc une solution plus C++-compliant (mais pas encore tout à fait, je vais y venir par la suite) est:
Le principe est du C pur (et n'est pas Ximoon-compliant ), tu dois pouvoir faire ça plus élégamment en C++ avec des exceptions, mais comme c'est pas mon domaine je laisse quelqu'un d'autre proposer une meilleure solution
#define FINALLY(cleanups) catch(...) {cleanups throw;} {cleanups}
// Create the button texture (transparent) and set it as render target
m_Texture = SDL_CreateTexture(Game::get()->renderer(), px, SDL_TEXTUREACCESS_TARGET, width, height);
if (m_Texture == nullptr) throw Exception(ERROR_SDL_STR);
try {
if (SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_BLEND) != 0) throw Exception(ERROR_SDL_STR);
if (SDL_SetRenderDrawColor(Game::get()->renderer(), 0, 0, 0, 0) != 0) throw Exception(ERROR_SDL_STR);
if (SDL_RenderClear(Game::get()->renderer()) != 0) throw Exception(ERROR_SDL_STR);
if (SDL_SetRenderTarget(Game::get()->renderer(), m_Texture) != 0) throw Exception(ERROR_SDL_STR);
} FINALLY(
cleanup();
)
Godzil (./1336) :
./1330: C'est moche plusieurs return dans une seul fonctionbool fonction1(void) { bool ret = false; // Create the button texture (transparent) and set it as render target m_Texture = SDL_CreateTexture(Game::get()->renderer(), px, SDL_TEXTUREACCESS_TARGET, width, height); if (m_Texture == nullptr) goto exit; if (SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_BLEND) != 0) goto exit; if (SDL_SetRenderDrawColor(Game::get()->renderer(), 0, 0, 0, 0) != 0) goto exit; if (SDL_RenderClear(Game::get()->renderer()) != 0) goto exit; if (SDL_SetRenderTarget(Game::get()->renderer(), m_Texture) != 0) goto exit; ret = true; exit: return ret; }
Voila c'est mieux
Folco (./1345) :Tu peux utiliser un nettoyeur générique:
Merci beaucoup Kevin, ça a l'air d'être bien le RAII, même si ça multiplie les classes (ce que j'aime pas trop).Par contre, si ça a l'air utile pour les objets dont la durée de vie est locale à une fonction, ça n'a pas l'air si approprié à mon cas : de multiples appels de fonction dans un constructeur. Ceci dit, je retiens cette technique d'encapsulation des ressources.
template <class T> Cleanup {
private:
T *m_p;
void (T::*m_pCleanup)();
public:
Cleanup (T *p, void (T::*pCleanup)()) : m_p(p), m_pCleanup(pCleanup) {}
~Cleanup() {m_p->m_pCleanup();}
}
// Create the button texture (transparent) and set it as render target
m_Texture = SDL_CreateTexture(Game::get()->renderer(), px, SDL_TEXTUREACCESS_TARGET, width, height);
if (m_Texture == nullptr) throw Exception(ERROR_SDL_STR);
Cleanup<MyClass> c(this, &MyClass::cleanup);
if (SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_BLEND) != 0) throw Exception(ERROR_SDL_STR);
if (SDL_SetRenderDrawColor(Game::get()->renderer(), 0, 0, 0, 0) != 0) throw Exception(ERROR_SDL_STR);
if (SDL_RenderClear(Game::get()->renderer()) != 0) throw Exception(ERROR_SDL_STR);
if (SDL_SetRenderTarget(Game::get()->renderer(), m_Texture) != 0) throw Exception(ERROR_SDL_STR);