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

Author Topic: Ignition Engine  (Read 10413 times)

0 Members and 1 Guest are viewing this topic.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10838
    • View Profile
    • development blog
    • Email
AW: Re: Ignition Engine
« Reply #15 on: January 11, 2014, 08:09:36 pm »
I only keep these template functions around for DX programming because from what I can tell, it is not safe to use C++11 smart pointers due to reference counting issues, and I don't want to clutter my code with both C++11 smart pointers and COM smart pointers.
The COM objects have their own reference counting, that's why a C++11 smart pointer can't be used directly. There are apparently ways, but why make it complicated if there are already dedicated "smart pointers"/RAII containers for it?

You should whatever is appropriate for the givrn situation, however excluding one because the others gets used doesn't make sense.
Use the COM smart pointer for COM objects and the C++11 smart pointers where ever there's no dedicated RAII mechanism. ;)

As for the topic, the process of learning to program, requires that a lot of code gets thrown away and rewritten newly. Refactoring is a must if you want to get a better programmer. This doesn't mean you can't reuse a lot of already written code, but it means one has to make fundamental changes. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Ignition Engine
« Reply #16 on: January 12, 2014, 02:12:19 pm »
Nowadays the C++ standard removes need for unnecessary checks.
Not nowadays, but since more than one and a half decade. C++ was standardized in 1998.

I only keep these template functions around for DX programming because from what I can tell, it is not safe to use C++11 smart pointers due to reference counting issues
Written in such a general way, that's wrong. I don't see a problem with reference counting, and not all smart pointers use it anyway. std::unique_ptr is a simple pointer wrapper that is just as fast as performing manual new/delete, and it's faster and much safer than your SafeDelete() function.

"Safe delete" is an abomination which inspired a lot of C++ developers to write questionable code, and unfortunately it has survived a long time, even though the original problems have disappeared long ago. One could even call it an anti-idiom; there's absolutely no sane reason to use it. This has nothing to do with C++11, smart pointers and RAII have been around for much longer (boost::scoped_ptr, std::auto_ptr). Even if those are not ideal nowadays and std::unique_ptr should be preferred, they're still much better than any way of managing memory or other resources manually.

If you're interested, read the RAII thread, we all tried to explain why RAII is such a powerful idiom that should be applied wherever possible.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Matt Guerrette

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
Re: Ignition Engine
« Reply #17 on: January 13, 2014, 10:08:26 am »
Nowadays the C++ standard removes need for unnecessary checks.
Not nowadays, but since more than one and a half decade. C++ was standardized in 1998.

I only keep these template functions around for DX programming because from what I can tell, it is not safe to use C++11 smart pointers due to reference counting issues
Written in such a general way, that's wrong. I don't see a problem with reference counting, and not all smart pointers use it anyway. std::unique_ptr is a simple pointer wrapper that is just as fast as performing manual new/delete, and it's faster and much safer than your SafeDelete() function.

"Safe delete" is an abomination which inspired a lot of C++ developers to write questionable code, and unfortunately it has survived a long time, even though the original problems have disappeared long ago. One could even call it an anti-idiom; there's absolutely no sane reason to use it. This has nothing to do with C++11, smart pointers and RAII have been around for much longer (boost::scoped_ptr, std::auto_ptr). Even if those are not ideal nowadays and std::unique_ptr should be preferred, they're still much better than any way of managing memory or other resources manually.

If you're interested, read the RAII thread, we all tried to explain why RAII is such a powerful idiom that should be applied wherever possible.

Again I would highly advise against using std::unique_ptr with DirectX COM objects.
http://msdn.microsoft.com/en-us/library/hh279683.aspx
illustrates the idea.

But to each his own I guess. I've already read up on RAII, and yes it can be a great idiom, but it really does depend on your target platform.

For example, I know some developers tend to stay away from RAII designs for embedded systems due to exception overhead.

Also, please stop re-iterating what I clearly already know, and have stated my reasons for keeping it around. Its not going to change the templates, really. Thanks!  :D

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10838
    • View Profile
    • development blog
    • Email
Re: Ignition Engine
« Reply #18 on: January 13, 2014, 10:56:56 am »
Written in such a general way, that's wrong. I don't see a problem with reference counting, and not all smart pointers use it anyway. std::unique_ptr is a simple pointer wrapper that is just as fast as performing manual new/delete
I think there could be a way to apply RAII to the whole COM stuff with unique_ptr and custom deleters, but I don't have any experience with it. From Microsoft however it's clear that they recommend using their COM smart pointers (see also here).

But to each his own I guess. I've already read up on RAII, and yes it can be a great idiom, but it really does depend on your target platform.

For example, I know some developers tend to stay away from RAII designs for embedded systems due to exception overhead.
Yes there are always exceptions to "rules", but exceptions are called exceptions because they are being used only in rare cases. Thus, avoiding RAII just because of such a possible exception is a bit ignorant to all the other cases. It's a bit like avoiding flying (and instead driving by car), because planes can crash, while ignoring the fact that chances for a plane crash are way lower than chances of having a car accident. ;)

Also, please stop re-iterating what I clearly already know, and have stated my reasons for keeping it around. Its not going to change the templates, really.
Fair enough, it's your code, so you can do with it whatever you want, but in return please stop recommending your personal hacks to the public, since you seem to know the things we're discussing here and know that RAII and a like are actually better and SAFE_DELETE is just a useless legacy thing. :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Ignition Engine
« Reply #19 on: January 13, 2014, 06:57:55 pm »
Sorry if you misunderstood that, I only meant it as good advice. You have made several statements where the exact opposite is true ("SAFE_DELETE is a good technique", "smart pointers are unsafe", "they incur always overhead", "exceptions are a reason not to use RAII").

To sum up: std::unique_ptr is exactly as efficient as plain new/delete. But it's safer and leads to less code, making your life easier.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

BruceJohnJennerLawso

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
    • My Code on Github
Re: Ignition Engine
« Reply #20 on: January 15, 2014, 04:32:56 am »
But automatic memory management is supposed to add some performance overhead when used, right? As I understood it, the only issue with C# is that the automated resource cleanup is automated, & a wee bit slower as a result?
Quote
The computer is mightier than the pen, the sword, and usually the programmer.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Ignition Engine
« Reply #21 on: January 15, 2014, 09:29:51 am »
But automatic memory management is supposed to add some performance overhead when used, right?
No, wrong. That's what I'm trying to explain all the time.

Look at a simple RAII example (ignore rule of three for the moment):
template <typename T>
struct SmartPtr
{
    explicit SmartPtr(T* raw) : ptr(raw) {}
    ~SmartPtr() { delete ptr; }

    T* ptr;
}

There is absolutely no reason why SmartPtr<X> p(new X); should be slower than X* p = new X; delete p;. All the functions can be inlined and the object consists only of the pointer, so the compiler will generate the same code for both. This is how std::unique_ptr works. std::shared_ptr is a different story, it is slower because of reference counting and thread safety.

As I understood it, the only issue with C# is that the automated resource cleanup is automated, & a wee bit slower as a result?
Garbage collection is not RAII. GCs indeed incur overhead, but they shine in situations where a lot of allocations have to be done, or where they can collect long-time information about memory usage.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

BruceJohnJennerLawso

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
    • My Code on Github
Re: Ignition Engine
« Reply #22 on: January 16, 2014, 04:30:02 pm »
Ah, that is good then. I guess you now have a new convert to smart pointers  :D

So if I define a smart pointer in a class, I need to initialize it in the constructor or some other method, and the pointer gets deleted when its scope ends, presumably the destructor of that object?

I assume rule of three means that I can only share the pointer between three different objects?
Quote
The computer is mightier than the pen, the sword, and usually the programmer.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10838
    • View Profile
    • development blog
    • Email
Re: Ignition Engine
« Reply #23 on: January 16, 2014, 04:51:33 pm »
So if I define a smart pointer in a class, I need to initialize it in the constructor or some other method, and the pointer gets deleted when its scope ends, presumably the destructor of that object?
I hope you're not talking about the smart pointer given by Nexus, because that's just an example OF a smart pointer, it doesn't show the USAGE of smart pointers.
A smart pointer can either point to a valid object or nullptr. If you initialize the smart pointer in the initialization list, it will directly point to an object, but you can also initialize it at a later point, but you'd have to make sure that the content is not a nullptr when you try to access the data.
For a unique_ptr the resource/memory gets freed as soon as the pointer runs out of scope. For shared_ptr the resource/memory gets freed only after all shared_ptr that reference the same object go out of scope.

I assume rule of three means that I can only share the pointer between three different objects?
No, he meant this.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

 

anything