Allegro.cc - Online Community
Post Reply

Allegro.cc Forums » Off-Topic Ordeals » Breaking your program ... on purpose

rss feed Print
Breaking your program ... on purpose
DanielH
Member #934
January 2001
avatar

So, everything is running smoothly and I decided to change something up river. Part of the framework. I wasn't happy with my object handler code. It is a basic wrapper for a std::unordered_map of objects. The problem was that the object being stored was a 'has'. I changed it to an 'is'. Then I had to rework everything down stream. Finally after a couple of hours it's back to running smoothly again.

Niunio
Member #1,975
March 2002
avatar

That's nothing.

My game engine has 4 alpha versions right now. Each one written from scratch because I didn't like how it looked after using them. Next one will be alpha.5, and again written from scratch 3 times. Yep, I've started from scratch alpha.5 3 times for different reasons.

Beat it. 8-)

-----------------
Current projects: Allegro.pas | MinGRo

Erin Maus
Member #7,537
July 2006
avatar

I recently added multithreading to my game (splitting logic and rendering into two separate threads). Broke so much stuff in the process. Some stuff is still broken a over month later.

I also moved large parts of the renderer to C++, which created rendering glitches. I think those are all fixed but there's still more rendering code that needs to be migrated...

I'm going to be adding support for multiplayer so massive breaking change #3 incoming.

---
ItsyRealm, a quirky 2D/3D RPG where you fight, skill, and explore in a medieval world with horrors unimaginable.
they / she

Polybios
Member #12,293
October 2010

In programming, the more you love it, the more you have to break it. 8-)

DanielH
Member #934
January 2001
avatar

I reworked the object system, then had to rework everything else.

Instead of storing the type in the object handler, I had to store the type in the object.

That meant, I couldn't just add a ALLEGRO_BITMAP to my handler.

So, I made a base object class with a single variable (int type).
And a derived wrapper sub class for Allegro objects.
Any custom objects are also derived from the main object class.

I also modified the manifest file. Display is still required, but the rest (timer, queue) I add in the background.

It's reworked and running great.

//Everying is loaded and/or created in the manifest parser
if (Parser::parseManifest(manifest_file) < 0)
{
  return -1;
}

// draw code
bool Game::OnRender(Allegro::Display& display)
{
  al_clear_to_color(al_map_rgb(0, 0, 255));

  Allegro::Font* font = static_cast<Allegro::Font*>(Object::getRegistry()->at("@font/main"));
  if (font)
  {
    al_draw_text(font->get(), al_map_rgb(255, 255, 255), 40, 40, 0, "Hello World!");
  }

  return false;
}

result
{"name":"613227","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/1\/916606dd990143214738360e83366eb9.png","w":1041,"h":818,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/1\/916606dd990143214738360e83366eb9"}613227

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

DanielH said:

Allegro::Font* font = static_cast<Allegro::Font*>(Object::getRegistry()->at("@font/main"));

That's terrifying.

Compare it to this :

...
   win->DrawText(font_registry->GetFont("font/main") , "Hello World" , 10 , 10 , EagleColor(255,255,255) , ALIGN_LEFT , ALIGN_TOP);

Anyway, if your font derives from an object, you need dynamic_cast, not static_cast.

Niunio
Member #1,975
March 2002
avatar

"C++ has become much better in the last ten years", they said... ::)

-----------------
Current projects: Allegro.pas | MinGRo

DanielH
Member #934
January 2001
avatar

Quote:

font_registry->GetFont("font/main")

That would require a registry for every object type.

Anyway, if your font derives from an object, you need dynamic_cast, not static_cast

Good to know. I'll fix them. static_cast and dynamic_cast weren't a thing when I learned C++.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

No, but maybe a function. Just an example.

inline Font* Registry::GetFont(Object* o) {
   return dynamic_cast<Font*>(o);
}
//... This is literally what I have in Eagle
win->DrawText(win->GetFont("Verdana.ttf") , "Hello Verdana" , 10 , 10 , EagleColor(255,255,255) , ALIGN_LEFT , ALIGN_TOP );

DanielH
Member #934
January 2001
avatar

Cast before or after. Still needs casting. Looks nicer, but accomplishes the same thing.

My get function needs the cast before because the compiler cannot differentiate functions based on the return type alone.

I could do what you say and write a get function for each type. The library does have known types, but the type system is extendable. The program can/will add types to it.

Peter Hull
Member #1,136
March 2001

You could also use simple templates

class ObjectRegistry {
...
 template <typename T>
 T at(const char* key) {
  return static_cast<T>(__at(key));
 }
};

where __at is the function that accesses the registry.
Use like

auto font = Object::getRegistry()->at<Allegro::Font*>("@font/main");

If there's only one registry that's global I suppose you could alternatively

template <typename T>
T get(const char* key) {
 return static_cast<T>(Object::getRegistry()->at(key));
}
...
auto font = get<Allegro::Font*>("@font/main");

DanielH
Member #934
January 2001
avatar

I originally had a templeted get function, then I realize I was casting twice.

oncein the get function

 template <typename T>
 T at(const char* key) {
  return static_cast<T>(__at(key));
 }

2nd at the get call

auto font = Object::getRegistry()->at<Allegro::Font*>("@font/main");

When I was doing the rewrite, I left out the template and left the getter return the base Object*.

Mark Oates
Member #1,146
March 2001
avatar

{"name":"613227","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/1\/916606dd990143214738360e83366eb9.png","w":1041,"h":818,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/1\/916606dd990143214738360e83366eb9"}613227

^^ What's the name of this fancy font you're using here? I feel like I need to embrace more fantasy fonts in my designs. 🤔

DanielH
Member #934
January 2001
avatar

I've had it for years. Can't remember where I got it. It's called ds_mysticora.

I just grabbed it for testing the font loading code.

Post Reply
Go to: