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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Nexus

Pages: 1 2 3 [4] 5 6 ... 394
46
SFML website / Re: a "beginners" board in forum?
« on: December 20, 2020, 10:48:56 pm »
I don't see any distinct enough scope that would justify a new section, either. Already now, new users often don't particularly care where they post help/beginner requests (just look at the General Discussions subforum), I don't think adding one more which highly overlaps with the existing ones will help the decision process.

Furthermore, I would not encourage users to ask even more C++-only questions -- there are enough places on the Internet with specialized communities, where more people can answer those quicker. Questions of the form "I'm learning SFML and C++ simultaneously" are already frequently asked and answered, even if their answer is often a pure C++ one and comes with a hint for good C++ resources.

47
Feature requests / Re: Animations and Particles
« on: December 18, 2020, 09:33:36 am »
SFML is a general-purpose multimedia library, which aims to provide the basic building blocks for easy and fast access to input, graphics and sound. It's not a game engine. The idea is that a lot of stuff, that easily can be built as an extension, is not part of SFML itself, to keep the API lean.

If you're interested in particle systems and animations, you could have a look at my extension library Thor: https://bromeon.ch/libraries/thor/

48
SFML projects / Re: Cellular automata with ImGui + SFML + Bazel
« on: November 02, 2020, 09:21:21 am »
Without looking at all the files, the SFML parts I've seen look good, maybe you should call window.clear(); in runner.cpp unconditionally (not sure what IMGUI does).

The state checking looks messy, why not an enum with running/paused/stopped?
Also, try to avoid global/static variables, they're often not needed with good design.

49
Pretty dramatic music for a game engine :P

Is the demo somehow interactive? If not, you might consider adding some interactive elements, and showcase more features directly.

The text on the rotating cogwheel is hardly readable, and the changing thickness looks a bit like a glitch. Maybe make it more smooth and consistent.

50
SFML projects / Re: Screenshot Thread
« on: October 31, 2020, 01:59:59 pm »
@Sinshu: great work, that looks really cool!

What parts did you use SFML for?
How did you do the 3D?

51
SFML development / Re: SFML Move Semantics
« on: August 03, 2020, 11:10:48 pm »
I can be biaised by what I need, but I suggest to first add move semantic for simple classes, that is which do not need custom logic.
For those, the compiler-generated move constructor/operator= would already do the correct thing, or am I misunderstanding you?

Which method to use may be important for consistency, but maybe there should be no more than few tens of classes that supports move semantics, so rewriting style from one method to another may take not long.
Yeah, since there hasn't been much feedback so far, I would suggest we choose one style and go for it. Doing it consistently still makes sense though. It's confusing for everyone if every move ctor/op= is implemented with a different idiom, and it creates needless work to refactor.

52
General discussions / Re: Thor and Animation
« on: August 03, 2020, 11:06:50 pm »
Regarding first post: the API changed a bit between Thor versions, in case of doubt generate the docs directly from source (Doxygen option in CMake).

Regarding second post: you're doing it extremely complicated, and with a large amount of boilerplate.
The normal algorithm is this:
sf::Vector2 vel;
if (up)
  vel.y -= 1;
if (down)
  vel.y += 1;
if (left)
  vel.x -= 1;
if (right)
  vel.x += 1;

// account for diagonal movement

53
SFML development / Re: SFML Move Semantics
« on: July 26, 2020, 11:20:36 am »
Regarding my PR, I'd like to get some feedback, also from other  SFML team members ;)

Anyone? :)
(also SFML users, not just team)

54
General / Re: The shortest possible way to resize my image?
« on: July 15, 2020, 07:31:00 pm »
SFML doesn't provide resizing, because there is no single algorithm for all purposes. There are in fact loads of scaling algorithms, all with different trade-offs. If you need one of them, you might want to look for a specific library.

As Hapaxia said, if you don't care about image quality/information loss, simply render a sprite to a render-texture and then save its contents. Don't forget to call display().

55
SFML development / Re: SFML Move Semantics
« on: July 09, 2020, 10:27:53 pm »
Those suggestions sound good. There are fortunately many classes in SFML, for which the default semantics work well.

But we need to be careful: sf::Image for example requires no special member functions at the moment (although there's a destructor doing nothing). However, a class with no special member functions declared is subject to implictly generated special member functions (aka Big Five). This would break in C++11, as a newly introduced move constructor does a member-wise move of each field, leaving the std::vector and sf::Vector2u fields inconsistent to each other. Ironically, the no-op destructor -- since declared -- prevents exactly that: sf::Image has no move ctor, even if compiled with a C++11 compiler.

Regarding my PR, I'd like to get some feedback, also from other  SFML team members ;)

56
SFML development / Re: SFML Move Semantics
« on: July 05, 2020, 01:25:15 pm »
A note worth mentioning is that if the internal handles were unique pointers then default move constructors would be perfect. Maybe this is a more valid approach for move semantics in some cases.
In sf::Shader, the private members are those:

    ////////////////////////////////////////////////////////////
    // Types
    ////////////////////////////////////////////////////////////
    typedef std::map<int, const Texture*> TextureTable;
    typedef std::map<std::string, int> UniformTable;

    ////////////////////////////////////////////////////////////
    // Member data
    ////////////////////////////////////////////////////////////
    unsigned int m_shaderProgram;  //!< OpenGL identifier for the program
    int          m_currentTexture; //!< Location of the current texture in the shader
    TextureTable m_textures;       //!< Texture variables in the shader, mapped to their location
    UniformTable m_uniforms;       //!< Parameters location cache

The two std::maps would move fine (emptying the source), but the integers will be copied. So, the default move implementation would leave a half-working instance behind.

As mentioned, in SFML we need to decide whether we give guarantees on moved-from objects or not.
For the sake of least surprise and simplicity, it might be more user-friendly to make moved-from objects behave like default-constructed ones.

In that regard, your current implementation is inconsistent:
sf::Shader a = ...;
sf::Shader b = std::move(a); // a is now empty
however:
sf::Shader a = ...;
sf::Shader b = ...;
b = std::move(a) // a now has contents of b

Since you already implement Move-and-Swap (but backwards), you might as well reuse swap() to always empty the source. In general, it's better to call the copy/move constructor in the copy/assignment operator, not vice versa.

A generic approach is this. It does a bit more than necessary, but this pattern can be applied everywhere, and the advantage is that the actual logic is in the swap() and only there --- move ctor/op= don't need to be changed when the fields change.
class Shader
{
    Shader();
   
    Shader(Shader&& moved)
    : Shader()
    {
        moved.swap(*this); // empties source
    }

    Shader& operator= (Shader&& moved)
    {
        Shader tmp(std::move(moved)); // invoke move ctor, empties 'moved'
        tmp.swap(*this);
        return *this;
    } // destroy 'tmp',

    void swap(Shader& other); // actual logic is here
}

We should also establish a naming convention for parameter names. For copy constructors, SFML currently uses copy. This is slightly misleading, as the parameter is the object being copied (origin) and not the copy (replica). In Thor I used origin and source, but I think we can be more precise.

What about copied and moved?
This makes it immediately clear that you're dealing with a copy or move ctor/op=.



[Edit] I made an example how I would probably implement it here:

https://github.com/SFML/SFML/tree/feature/move-semantics

One commit with unified copy/move op=, the whole branch diff with separate ones.
Not tested -- those things might be a candidate for unit tests.

57
SFML development / Re: SFML Move Semantics
« on: July 05, 2020, 12:46:57 pm »
However, I really want behaviour to be logical, and I don't think that swapping internal state for resources like windows during move operations is logical.

A classical implementation of Copy-and-Swap would be like this:
class Image
{
        Image();
        Image(const Image& copied);
        Image(Image&& moved);

        void swap(Image& other);

        Image& operator= (const Image& copied) {
                Image tmp(copied);
                tmp.swap(*this);
                return *this;
        } // object 'tmp' (with previous contents of *this) is destroyed

        Image& operator= (Image&& moved)
        {
                moved.swap(*this);
                return *this;
        } // object 'moved' (with previous contents of *this) is destroyed
};

Since the temporary object is destroyed after a copy operation, it does not matter what it contains. A moved-from object is typically destroyed after the move as well, but there are exceptions like std::unique_ptr which define a behavior. So, unless SFML would explicitly guarantee that a moved-from image is equal to an empty image, we can put any valid content into moved-from objects. Otherwise we would simply involve a default-constructed object to "reset" the image after moving.

The reason why this idiom exists in the first place, is because the naive (or compiler-generated) implementation does this:
        Image& operator= (const Image& copied)
        {
                member0 = copied.member0;
                member1 = copied.member1;
                // ...
                memberN = copied.memberN;

                return *this;
        }

        Image& operator= (Image&& moved)
        {
                member0 = std::move(moved.member0);
                member1 = std::move(moved.member1);
                // ...
                memberN = std::move(moved.memberN);
       
                return *this;
        }

Now imagine that during "...", an exception occurs while copying/moving. The assignment operation is aborted, but both objects are in an inconsistent, "half-moved" or "half-copied" state. This is mostly a problem for copies, as moves should be designed to not fail (however, this is not always possible, e.g. when moves fall back to copies, for raw arrays for example).

What Copy-and-Swap does is -- instead of overwriting the object in-place -- first creating a new valid object, swapping with that and then destroying the old one. Since both swap and destroy operations should not fail, only the construction of the new object can fail, in which case the object is left in the previous, valid state.




So much about the theory. What I mentioned above is absolutely crucial when designing generic building blocks like containers, smart pointers, graphs or other data structures. You don't know what the user will put inside, so you have to assume copies can fail, and design the code accordingly.

Now, in practice, you often have better knowledge about what types are involved, and can exploit this knowledge to simplify code. If SFML resorts to not throwing exceptions during copy/move operations, and has no APIs where user-defined types could trigger exceptions, we can avoid the extra effort and try to use the compiler-generated methods where possible.

Pragmatically, I would attempt to use default move (and even copy) constructors/assignment operators wherever possible -- it's just so much easier to reason about code, to add new fields, etc. But since SFML operates with resources in several places, it involves custom ownership semantics here and there. These are the cases we need to analyze and determine what is the greatest common denominator.

58
SFML development / Re: SFML Move Semantics
« on: July 04, 2020, 11:10:12 am »
First, there are different levels of exception guarantees, specifying how involved objects behave in the presence of exceptions:
  • strong - every object is always in a semantically valid state
  • basic - every object is still destructible and doesn't evoke UB
  • none - no guarantees

There are several idiomatic ways to implement the special member functions with C++11, to sum up:

1. Rule Of Five
Overload copy/move ctor, copy/move op= and dtor.
This is the "stupid" approach which requires a big amount of boilerplate, code duplication and thus is rather prone to errors when extending a class.

2. Copy-and-Swap
Overload all 5 special methods + swap(). Use swap() in copy/move op=.
Avoids some code duplication, but still a lot of boilerplate.
Achieves strong exception guarantee (each object is always in a valid state).

3. Rule of Four-and-a-half
Overload copy/move ctor and dtor as usual.
Overload op= taking a value (not const- or rvalue-reference), which means it acts as both move and copy assignments.

4. Rule of Zero
Let the compiler generate the Big Five.
Code complexity wise, this is the best solution, as the behavior is clear and no member can be forgotten. It does not work when there are complex ownership rules, or custom copy logic (for handles).
I've found my smart pointer aurora::CopiedPtr to be a very nice fit for pointers which require deep copies. It can easily reduce the number of methods needed from 5 to 0. For example, in Thor I need it for quite a few things.
Downside: with compiler-generated member-wise copy, the exception guarantee is often reduced to basic (when the copy operation aborts in the middle).

I'm wondering if strong exception guarantee is something we really have to go for in SFML. Generally, I'm more in favor of readable/compact code. Having to implement the Big Five for every 2nd class is also often an indication of bad ownership design or lack of internal abstraction (too many types have custom ownership rules).

59
General / Re: thrown exception to draw?
« on: June 27, 2020, 01:09:42 pm »
Based on the address, it looks like you're dereferencing a null pointer.

Also read this post and follow the instructions.

60
Feature requests / Re: why sfml not support dds image type
« on: June 27, 2020, 01:02:33 pm »
SFML doesn't just support every possible image format for the fun of it. These formats are not very common in our domain, so few users would benefit from them.

If you disagree, maybe elaborate common use cases and argue why those would be a great addition to SFML. Also, it would definitely help to present a strategy towards implementation, as resources are limited ;)

Pages: 1 2 3 [4] 5 6 ... 394
anything