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 - Garwin

Pages: [1] 2 3 4
1
You can use variadic templates but is quite unsafe.
I did not check the code, hope it is correct.

auto isAnyKeyPressed(auto... keys) -> bool
{
    return (sf::Keyboard::isKeyPressed(keys) || ...);
}
 

Now you can use just:
if (isAnyKeyPressed(sf::Keyboard::A, sf::Keyboard::D, sf::Keyboard::W, sf::Keyboard::S))
    // make stuff there

 

Problem with the code is:
1. It does not check type of arguments but at least it will generate errors if any parameter is not convertible to enum sf::Keyboard::Key
2. It has even more issues as sf::Keyboard::Key is unscoped enum which can make error messages even tougher to get to the point of error. And it can accept even incorrect parameter.

You can limit template with Concept but issue of unscoped Enum remains.

2
Graphics / Re: origin relative to the Transformable
« on: September 06, 2024, 09:05:26 am »
I cannot speak of SFML team. But you can easily add template that handles that for each Transformable.

#include <SFML/Graphics/Transformable.hpp>
#include <type_traits>

template <typename T>
concept SfTransformable = std::is_base_of_v<sf::Transformable, T>;

void setOriginToCenter (SfTransformable auto& sfTransformableObject)
{
    sfTransformableObject.setOrigin(sfTransformableObject.getLocalBounds().getPosition()
        + (sfTransformableObject.getLocalBounds().getSize() / 2.f));
}
 

Now you can try if it works. It would even work for your graphical entities based on sf::Transformable.

#include <SFML/Graphics.hpp>

int main ()
{
    sf::RectangleShape shape;
    setOriginToCenter(shape);

    sf::Text text;
    setOriginToCenter(text);

    int a;
    //setOriginToCenter(a); // error - do not pass concept SfTransformable

    sf::Vector2f vec2f;
    //setOriginToCenter(vec2f) // error - do not pass concept SfTransformable

    return 0;
}
 

3
SFML development / Re: SFML 3.0 std::optional
« on: July 30, 2024, 05:39:27 pm »
You are completely right about RVO. It is possible to see with updated example.
https://godbolt.org/z/PEWvjoYdW

Nevertheless, I would still create directly std::optional<T> instead of creating T and later return created std::optional<T>. This will save one construction and destruction of T.

4
Graphics / Re: Y-Axis in math functions
« on: July 29, 2024, 09:36:00 pm »
...

Thanks, you are completely right, and practically, it needs minimal changes of code.

5
SFML development / SFML 3.0 std::optional
« on: July 29, 2024, 09:34:10 pm »
I have just looked at the main branch of SFML 3.0 and see that it uses std::optional.

However, it seems to me that implementation is done in a way that there are additional copies done as this way there is no RVO on return values. (see showVer1)
The relatively small change can correct this (see showVer2 or showVer3).
Practically instead of making object T and then returning object T, we need to create object std::optional<T> and return that object.

I have prepared an example on Godbolt.
https://godbolt.org/z/PTc39hMa8

6
Graphics / Y-Axis in math functions
« on: July 27, 2024, 07:50:21 pm »
SFML has a Y-axis oriented down but other uses (OPEN GL, graphs visualization, usual math representation) have Y-axis up. How to solve that in math functions that give completely different results based on the orientation of the Y-axis.
The main functions that give different results based on orientation are isClockwise, isCounterClockwise, objectOrientation and any sorting of points based on clockwise order.

I have thought about it but I would like to know how is it solved in professional programming. My thoughts of possibilities.

1. Macro
Define macro for AXIS_Y to be +1 or -1 depending on orientation.
Advantages:    Easy, efficient (compile time)
Disadvantages: Ugly, the whole application needs to use the same orientation of the Y-axis

2. Function name
Define a pair of functions in each case.
Advantages:    Efficient (compile time)
Disadvantages: Ugly for naming, duplicate code.

3. Function parameter
Each function has an additional last parameter with orientation of Y-Axis and it can even be defaulted in function and even the default can be set by macro.
Advantages:    Easy, easy to maintain.
Disadvantages: Less efficient (runtime)
note: default changed by macro seems like a nest for potential bugs in case of change, the default parameter of a function can be an easy way for bugs to forget to pass the orientation of the Y-axis.

4. Functor
Make a helper implementation class with an overloaded operator (), a static member of the orientation of the axis with a static function to change orientation to up or down. Then make a static variable of the class that is used to call a functor.
Advantages:    Work as a standard function, Axis orientation is preserved between calls but can be changed calling the static member function
Disadvantages: Less efficient (runtime)

5. Template
Make a template with the type to choose axis orientation. Then there can be constexpr branches.
Advantages:    Efficient (compile time)
Disadvantages: not user-friendly, code will be not so obvious

So questions are:
- How is it solved in professional? (I am just a hobbyist)
- Are there any other better possibilities?

7
General / Re: Check if SFML is installed
« on: June 24, 2024, 11:13:20 am »
You can use macros not exactly what you ask but still can help you to detect certain header file.
#if __has_include
https://en.cppreference.com/w/cpp/preprocessor/include

eg.:
#if __has_include("SFML/System/Vector2.hpp")
    #include <SFML/System/Vector2.hpp>
    #define has_sfVector 1
#else if
    #define has_sfVector 0
#endif // __has_include("SFML/System/Vector2.hpp")


 


8
General / Re: Failed to load image
« on: March 11, 2024, 07:21:02 am »
Do you run the program directly or through IDE? Usually, IDE has working space and could be different than where you have exe files.

9
System / Vector2 - type safety between Point and Vector (dimension)
« on: March 10, 2024, 09:31:46 am »
I have recently used Vector2 for several functions, in some cases as Point and in some cases as Vector (dimension).
I have found that it is not the best especially if function parameters need both, point/s and vector/s.
I have created class Line which just has two points and an enum for line type (straight, ray, segment).
It was much better and safe however, it needs to create a line and sometimes you have just a point and vector or two points.

So another step is to split general sf::Vector2 into two types:
- Point2
- Vec2
And define operations over them. I found it as really big advantage as it can forbid meaningless operations.
Point2f pointA {1.f,1.f};
Point2f pointB {2.f,2.f};
Vec2f vecA {3.f, 0.f};

auto bLessA = pointB - pointA; // bLessA is Vec2f because operand- for two points are not defined
auto pointC = bLessA + vecA; // Error as there is no overloaded operand+ for two points
auto aAddVecA = pointA + vecA; // type is Point2f

This allows me to define function parameters much more safely (used C++20):

template <typename T>
concept arithmetic = std::integral<T> || std::floating_point<T>; // more strict definition to general definition

template <arithmetic T>
auto linesIntersection (const Point<T>& pointA, const Vec<T>& vecA, const Point<T> pointP, const Vec<T>& vecP)
-> std::optional<Point<T>>;

template <arithmetic T>
auto linesIntersection (const Point<T>& pointA, const Point<T>& pointB, const Point<T>& pointP, const Point<T>& pointQ)
-> std::optional<Point<T>>;
 

Would not be useful that type safety even for SFML?

10
Graphics / Re: setFrameLimit - curious effect
« on: February 20, 2024, 09:18:26 am »


Thanks for confirming, that I am not completely out of mind.
It should be no problem as if the application is more processor demanding, there will be less sleep, so no slow down.

11
Graphics / Re: setFrameLimit - curious effect
« on: February 15, 2024, 07:34:04 pm »
setFramerate() sleeps the thread.
This helps with "over-producing" with no limit and can reduce power used. However, it's not strictly set to that rate.
Once a thread is "slept", it has the possibility of "over-sleeping" as there's no real way of insisting on coming back by a specific time (accurately); this is dependent on operating system's task scheduler.

So, I'd guess that the framerate limit is sleeping during each frame and then the operating system is keeping it a little longer than your hoped-for length of time before returning it.

I would expect it to be faster (shorter frame time) without a framerate limit.

This I would understand but if the measurement of the function is just 2 time points one before that function and after that function which has no call to SFML except sf::Vector2f, that I cannot see how sleep will interfere with it. I do not measure and compare whole loop but only one function inside the loop.

12
Graphics / setFrameLimit - curious effect
« on: February 14, 2024, 05:50:43 pm »
I am just curious as it is nothing really important.

I have just measured in average on function that generate Voronoi diagram which is inside the main sfml event loop.

auto vorStartTime = std::chrono::steady_clock::now();
            voronoi.generate();
auto vorEndTime = std::chrono::steady_clock::now();
 

Then I print each second the average for this function. Each iteration I add vorEndTime - vorStartTime to the overall time and then divide by a number of loops for that time. Than just checking if elapsed at least 1 second from the last loop and if so print the average.

But what is really strange that it gives me 0.3 - 0.6 ms with setFrameLimit to 60.
But if I switch off any FrameLimit, i get 0.14 - 0.16 ms.

The function
voronoi.generate() is using only sf::Vector2f from the whole SFML library for points.
 


I am just curious how it can be possible that setting frame limit has effect on function with has practically nothing to do with SFML. Or it can be possible that setting the frame limit makes the processor more idle so that the max turbo frequency of processor is not used (intel i7-1265u 1.8 MHz)

13
Graphics / Re: sf::Rect
« on: February 10, 2024, 12:16:00 pm »
Good, there is static_cast to show an intention.

However, a much more difficult area is floating point math and comparison of floating points. Mostly, you want the warning as it is unintentional but there are cases in which you want to compare floating points for equality and there is no way to tell the compiler to ignore this case and not issue a warning.

14
Graphics / Re: sf::Rect
« on: February 05, 2024, 05:29:14 pm »
I would guess it's there to make sure the type is T to match the min and max signature.
For integer datatypes, the type of the result of a + is not always the type of the two operands. If you have a Rect<short>, then left and width are shorts, but left+width is an int.
(From cppreference.com: "In particular, arithmetic operators do not accept types smaller than int as arguments")
Thanks, forgot about this specifiation.

15
Graphics / sf::Rect
« on: February 04, 2024, 09:12:06 am »
I have looked at the implementation of the Rectangle class and I was surprised to find static_cast.

Why is static_cast there?

from SFML 3.0 branch
template <typename T>
constexpr bool Rect<T>::contains(const Vector2<T>& point) const
{
    // Not using &#39;std::min&#39; and &#39;std::max&#39; to avoid depending on &#39;<algorithm>&#39;
    const auto min = [](T a, T b) { return (a < b) ? a : b; };
    const auto max = [](T a, T b) { return (a < b) ? b : a; };

    // Rectangles with negative dimensions are allowed, so we must handle them correctly

    // Compute the real min and max of the rectangle on both axes
    const T minX = min(left, static_cast<T>(left + width));
    const T maxX = max(left, static_cast<T>(left + width));
    const T minY = min(top, static_cast<T>(top + height));
    const T maxY = max(top, static_cast<T>(top + height));

    return (point.x >= minX) && (point.x < maxX) && (point.y >= minY) && (point.y < maxY);
}
 

Pages: [1] 2 3 4