Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Interface for "loadFromFile" (and others)  (Read 3292 times)

0 Members and 1 Guest are viewing this topic.

Glocke

  • Sr. Member
  • ****
  • Posts: 289
  • Hobby Dev/GameDev
    • View Profile
Interface for "loadFromFile" (and others)
« on: November 28, 2014, 03:25:13 pm »
Hi, an interface for all SFML-classes providing loadFromFile() (and similar) would be great. I'd like to store multiple "Loadables" inside a nested std::map: First key: RTTI using std::type_index(typeid(...)), second key: actual identifier to the resource (e.g. std::string). Because those resources have no common parent class, the final type (which to embedd in the inner std::map) needs to be void* which isn't great for polymorphic stuff.

Btw my map looks currently like this:
std::map<std::type_index,
    std::map<std::string, void*>
>
because I store pointers to different resources. The desired map would look like this:
std::map<std::type_index,
    std::map<std::string, std::unique_ptr<sf::Loadable>>
>

Also this would allow to dynamic_cast instead of static_cast. Casting statically is not helpfull if you're using polymorphism. Else, dynamically casting provides this - but void is not a base class for any of the used types ^^

Why not using a single std::map per resource type? I wrote a private template-based get/set for this entire map. The public interface calls this methods with a concrete type (e.g. sf::Texture). But I don't want to copy'n'paste the entire mechanisms for each new resource type. A "Loadable" interface would help, because I could derive my own resources (such as file streams) from Loadable and use them (just as sf::Texture if implementing Loadable^^) as polymorphic loadables.

Does anyone like this idea?
« Last Edit: November 28, 2014, 03:26:45 pm by Glocke »
Current project: Racod's Lair - Rogue-inspired Coop Action RPG

Strelok

  • Full Member
  • ***
  • Posts: 139
    • View Profile
    • GitHub
Re: Interface for "loadFromFile" (and others)
« Reply #1 on: November 28, 2014, 03:48:57 pm »
You might want to have a look at Thor (sfml extension)

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Interface for "loadFromFile" (and others)
« Reply #2 on: November 28, 2014, 04:21:08 pm »
Because those resources have no common parent class, the final type (which to embedd in the inner std::map) needs to be void* which isn't great for polymorphic stuff.
You're thinking the Java way. In C++, types need not have a common base class in order to be used polymorphically. Of course, there are situations where class hierarchies come in handy, but it's not a per-se requirement.

Instead, have a look at type erasure. It's a very powerful C++ concept that combines static and dynamic polymorphism, and it allows you keep type safety without coupling types unnecessarily through inheritance. All this without void* in the API.

Also this would allow to dynamic_cast instead of static_cast. Casting statically is not helpfull if you're using polymorphism.
That is a deterioration. Almost always, dynamic_cast indicates a design flaw, because you're not sure about the dynamic type and have to try it. For downcasting, static_cast should be the default approach, dynamic_cast should be mainly a debug error check in combination with assertions.

As indicated by Strelok, I already wrote a resource-loading abstraction in Thor. See Resources module and tutorial. thor::MultiResourceCache could be interesting for you, as it's a type-erased resource manager. It's currently conceived for shared ownership and automatic duplicate resolution, and thus possibly too complicated for average cases, but I plan to provide a simplified version in the future.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Glocke

  • Sr. Member
  • ****
  • Posts: 289
  • Hobby Dev/GameDev
    • View Profile
Re: Interface for "loadFromFile" (and others)
« Reply #3 on: November 28, 2014, 04:26:56 pm »
You're thinking the Java way.
Well, this is the OOP way - not only the java way ^^

Instead, have a look at type erasure. It's a very powerful C++ concept that combines static and dynamic polymorphism, and it allows you keep type safety without coupling types unnecessarily through inheritance. All this without void* in the API.

I recently discovered dynamically and static casting (to replace old C-style casts). Because of decoupling, my first idea was the stated interface :)

Almost always, dynamic_cast indicates a design flaw, because you're not sure about the dynamic type and have to try it. For downcasting, static_cast should be the default approach, dynamic_cast should be mainly a debug error check in combination with assertions.

Ok thx! :)

About Thor: Yes I already know ;) I'm currently playing around with concepts and ideas.
Current project: Racod's Lair - Rogue-inspired Coop Action RPG