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

Author Topic: Thor 2.0 released!  (Read 381861 times)

0 Members and 7 Guests are viewing this topic.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
[Thor] Animation tutorial
« Reply #240 on: October 16, 2013, 01:43:37 pm »
I finally wrote a tutorial about the Animation module. It will be extended over time :)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

didii

  • Full Member
  • ***
  • Posts: 122
    • View Profile
Re: Thor 2.0
« Reply #241 on: November 27, 2013, 10:31:25 pm »
If I would write the following
thor::UniversalEmitter emitter;
emitter.setParticleVelocity(thor::Distributions::uniform(-100.f,100.f));
for which the syntax is correct but will give an error wrong since thor::UniversalEmitter::setParticleVelocity needs a sf::Vector2<float> and thor::Distributions::uniform will return a float. When building, I get an error referring to
Code: [Select]
xrefwrap(431): error C2664: 'sf::Vector2<T>::Vector2(const sf::Vector2<T> &)' : cannot convert parameter 1 from 'float' to 'const sf::Vector2<T> &'which is quite confusing since you have no idea where the error comes from if you are not familiar with functors and/or Thor. Is there a possibility to separate the distributions according to their return type? Or is this error common while using functors?

I do have to note that I'm not familiar with functors and have no idea if it is possible at all. Also, I'm sorry if this has already been mentioned, I only did a very quick search on these 17 pages..



EDIT: I'm sorry, should have read 1 page more about functors before commenting here. So it does not seem possible to do this for which the compiler can notice the mistake from where it actually happens. It does seem to be possible to do this with functions though, but I can see the downsides of that.
Defining an abstract base template class won't work either since you are again stuck with the number of arguments... Is it really impossible to restrict the return types on functors? It seems so unlikely that you would accept and use a function without ever knowing which type it will return. Hoping that the user will use it correct is generally a bad practice...

EDIT2: oh, I used the most recent version of Thor btw right from your GitHub.
« Last Edit: November 27, 2013, 11:08:15 pm by didii »

didii

  • Full Member
  • ***
  • Posts: 122
    • View Profile
Re: Thor 2.0
« Reply #242 on: November 28, 2013, 01:47:26 am »
Now I feel embarrassed... So much mistakes were made from my side. I should now have found the problem, so let me rephrase everything.

When I give thor::UniversalEmitter::setParticleVelocity as input argument a thor::Distributions::uniform, the compiler accepts the argument and shows an error in xrefwrap instead. Below is a minimal working example. I have absolutely no idea why the compiler accepts a wrong input parameter. And I cannot seem to replicate it. I have already tried creating a uniform class/struct that inherits from Distribution<float>, getting the exact same error.

#include <Thor/Particles/Emitters.hpp>
#include <Thor/Math/Distributions.hpp>

int main() {
        thor::UniversalEmitter emitter;
        emitter.setParticleVelocity(thor::Distributions::uniform(-100.f,100.f));

        return 0;
}

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Thor 2.0
« Reply #243 on: November 28, 2013, 08:59:26 am »
I have absolutely no idea why the compiler accepts a wrong input parameter.
It does not accept it, otherwise there would be no error. With templates, there are mostly multiple error messages, each referring to a separate layer in the problematic call. If you scroll down, you will find the error in user code.

I agree that a compiler error in the depths of the std::function implementation is not ideal, but there's not much I can do about that. But even then, the first error message is quite expressive:
cannot convert argument 1 from 'float' to 'const sf::Vector2<float> &'

Is it really impossible to restrict the return types on functors? It seems so unlikely that you would accept and use a function without ever knowing which type it will return.
The return type is clear for a given function in the thor::Distributions namespace and for given argument types. In C++, a function cannot just return "anything", there's always a type.

Hoping that the user will use it correct is generally a bad practice...
I don't hope, I expect him to use it correctly... For some reason there is the documentation ;)
« Last Edit: November 28, 2013, 10:58:12 am by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

didii

  • Full Member
  • ***
  • Posts: 122
    • View Profile
Re: Thor 2.0
« Reply #244 on: November 28, 2013, 11:58:15 am »
It does not accept it, otherwise there would be no error. With templates, there are mostly multiple error messages, each referring to a separate layer in the problematic call. If you scroll down, you will find the error in user code.
Indeed, in the 14th layer I can indeed see the referral to the main function :D So the actual 'problem' lies in the usage of different templates? Then probably Intellisense is also not made to look in such a depth. Thanks for clearing that up.

The return type is clear for a given function in the thor::Distributions namespace and for given argument types. In C++, a function cannot just return "anything", there's always a type.
Like I said in my second post. Disregard my first one, didn't see a lot of things. You indeed restrict its return type, but I thought, if you simply use
template <class C> void myFunc(C functor);
You are asking for any functor with any return type right? It just seems so unlikely for C++ to do such a thing. But if I now look at it, it's a template so you are in fact explicitly allowing it...

I don't hope, I expect him to use it correctly... For some reason there is the documentation ;)
Again, disregard my first post :)

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Thor 2.0
« Reply #245 on: November 28, 2013, 01:15:55 pm »
The problem is that you use Distribution<float> although Distribution<sf::Vector2f> is expected. std::function will still try to convert it somehow, leading to an error in its depths.

Note that he documentation of thor::Distribution<T> is simplified at that point, there's a lot of black magic going on behind the scenes. The actual constructors of thor::Distribution<T> are declared as follows, where AURORA_ENABLE_IF is a macro that activates the overload given the condition is true, according to SFINAE:
template <typename U>
Distribution(U constant
        AURORA_ENABLE_IF(std::is_convertible<U, T>::value));

template <typename Fn>
Distribution(Fn function
        AURORA_ENABLE_IF(!std::is_convertible<Fn, T>::value));

This is a very sophisticated way of overload resolution, but it allows me to differentiate between constants and functions passed to distributions. Ideally, I would just have two overloads that take T and std::function<T()>, however this doesn't work with implicit conversions. People expect to write emitter.setParticleRotation(90) although 90 is an int and not a float. So there would be two implicit conversions: int -> float -> Distribution<float>, and this is disallowed by the C++ standard.

Actually, that gives me an idea: I can extend these checks to create a clearer error message. But tinkering with black magic is always dangerous, I need to test some time. And that brings me to a general question: Should Distribution<T> be convertible to Distribution<U> if T is convertible to U (as it is now)? Or only explicitly? Hm... ???
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

didii

  • Full Member
  • ***
  • Posts: 122
    • View Profile
Re: Thor 2.0
« Reply #246 on: December 02, 2013, 04:05:58 pm »
Should Distribution<T> be convertible to Distribution<U> if T is convertible to U (as it is now)? Or only explicitly? Hm... ???
In my opinion it's always more safe to only use explicit conversions. I like the way current C conversions happen: allow it, but display a (compiler) warning. But I suppose this is impossible without altering the compiler.
Allowing the conversion gives the user a more freedom and less tedious (and in a lot of cases unnecessary) conversions, but this does withhold users who are newer to C++ to learn that there is an actual difference between writing 90, 90. and 90.f. So it's your target audience or the reason behind the creation of Thor that matters I suppose.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Thor 2.0
« Reply #247 on: December 02, 2013, 07:30:25 pm »
In my opinion it's always more safe to only use explicit conversions.
Thanks for the input! Generally, I share this opinion, but I thought about it again and found a very important argument:

If I allow a Distribution<T> to be initialized with a function with return type U (convertibility given), I must allow conversions from Distribution<U> to Distribution<T> as well, because distributions are functors like any other.

The only alternative would be to completely forbid functors whose types don't match exactly the distribution's declaration type. This might not only be too restrictive, but it contradicts the way how conversions are handled in C++ (std::function and between basic types). The following code is fine:
std::function<int()> f = [] () { return 4l; };

Requiring explicit conversions would probably confuse a lot of people. thor::Distribution is just a thin wrapper around std::function, and it interacts with basic types very closely. It doesn't introduce unexpected or dangerous conversions, only those that would already be possible if a distribution object were a value (in other words: the expected ones). That's why I'm leaving the implicit conversions as they are.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
[Thor] New joystick actions
« Reply #248 on: December 04, 2013, 11:41:44 pm »
Changes in Joystick API

First, there were some renamings for the sake of clarity and expressiveness:
  • thor::Joystick class -> thor::JoystickButton
  • thor::Joystick::id variable -> thor::Joystick::joystickId
  • thor::Joy() constructor -> thor::joy() function
Second, and this is the important part, I added the class thor::JoystickAxis. Similar to thor::JoystickButton, it represents the state of a joystick axis as it is used for the action system. The class thor::Action was extended by an additional constructor for joystick axes.

What you can do now is associate an action with a joystick threshold exceedance. For example, if you want to react to a Y axis position of joystick 0 above 25%, you can now do this:
thor::Action action(thor::joy(0).axis(sf::Joystick::Y).above(25.f));

There is also a below() function for the less-than relation. This syntax is similar to the existing one for buttons ("is button 2 of joystick 0 pressed?"):
thor::Action action(thor::joy(0).button(2));
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Re: Thor 2.0
« Reply #249 on: December 12, 2013, 08:29:54 pm »
The project seems to be interessant but some things in the that library are too complexe for me. (and unflexible)
By example : the resource system. :S

A resource holder with a simple template and an identifier which is stored into a multi-cache (by using a transtypage from the typename to a void* (type erasure) into a container like a vector or a map) should do the trick.

So you can add any fonctions that you want in the resource manager class without forcing the developper to use a shared pointer and a specific fonction/identifier to load a resource. :)

Example :
load (resource, identifier) instead of key = ...




« Last Edit: December 12, 2013, 08:33:39 pm by Lolilolight »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Thor 2.0
« Reply #250 on: December 12, 2013, 08:38:31 pm »
I know -- I frequently state that thor::ResourceCache shouldn't be overused, it is for special cases with shared ownership and automatic duplicate recognition. In cases where these features are required, it is really powerful, which comes at a cost for simpler use cases.

As you can see here, a more lightweight alternative to thor::ResourceCache is already planned :)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Re: Thor 2.0
« Reply #251 on: December 13, 2013, 10:42:51 am »
Ok, it's nice because, in my system I don't need duplicate recognition and shared ownership. :)

I simply need something like this : (The resource manager contains 1 or several resources, and, the cache contains the resource managers, so the resource manager is also the key.)

//Declaration and resources loading.
ResourceManager<Texture> text1;
text1.load("path1");
ResourceManager<Texture> text2;
text2.load("path2");
//Add the resources to the cache.
Cache cache;
cache.add<Texture>(text1);
cache.add<Texture>(text2);
//Get a resource from the cache by his variable name.
const Texture* text = cache.get<Texture>(text1);
//Retrive the path to the ressource. (To save them in a file later)
vector<string> paths = cache.getPaths();
 

Or, a second method is also possible, if he wants to use a string (with one texture manager for each textures) :

//Declaration and resources loading.
ResourceManager<Texture> textures;
textures.load("path1", "alias1");
textures.load("path2", "alias2");
//Add the resources to the cache.
Cache cache;
cache.add<Texture>(textures);
//Get a resource from the cache by his alias.
const Texture* text = cache.get<Texture>("alias1");
//Retrive the path to the ressource. (To save them in a file later)
vector<string> paths = cache.getPaths();
 

The inconvenient of the second method is that if he mistakes the string name it'll crash at the execution.
The advantage is that he don't have to keep the resource manager name to get the resource.

In the first method, this is juste the inverse : It'll won't compile if he mistakes the variable name but he must keep the variable name to retrieve the resource.
« Last Edit: December 13, 2013, 10:44:46 am by Lolilolight »

The Terminator

  • Full Member
  • ***
  • Posts: 224
  • Windows and Mac C++ Developer
    • View Profile
Re: Thor 2.0
« Reply #252 on: December 14, 2013, 12:31:01 am »
Hi there, I wanted to adapt my GUI classes (mainly buttons and radioboxes) to the callback systems on thor, but unfortunately the "Connecting callbacks" tutorial does not compile on GCC 4.7.1. I have heard there are bugs on passing references to functions, is this true? Or is there a problem with thor?
Current Projects:
Technoport

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Thor 2.0
« Reply #253 on: December 14, 2013, 12:45:53 am »
Hi there, I wanted to adapt my GUI classes (mainly buttons and radioboxes) to the callback systems on thor, but unfortunately the "Connecting callbacks" tutorial does not compile on GCC 4.7.1. I have heard there are bugs on passing references to functions, is this true? Or is there a problem with thor?
I assume you're referring to the Actions tutorial.

Can you show a minimal and complete code example with the corresponding error message?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

The Terminator

  • Full Member
  • ***
  • Posts: 224
  • Windows and Mac C++ Developer
    • View Profile
Re: Thor 2.0
« Reply #254 on: December 14, 2013, 06:09:34 pm »
Yes I am. Here's a small snippet from my own engine:

Button.hpp:

    class Button : public GUIObject
    {
    public:
        enum class Button_Actions
        {
            CLICKED
        };

        Button(const std::string& textString, const std::string& fontPath, const sf::Vector2f pos,
                    int charSize, const sf::Color& defaultColor, const sf::Color& activatedColor,
                     bool alwaysDraw);

        void onClick(thor::ActionContext<Button_Actions> context)
        {
            std::cout << "test" << std::endl;
        }

    protected:
        thor::ActionMap<Button_Actions> m_map;
        thor::ActionMap<Button_Actions>::CallbackSystem m_system;

    };

Button.cpp:

    Button::Button(const std::string& textString, const std::string& fontPath, const sf::Vector2f pos,
                   int charSize, const sf::Color& defaultColor, const sf::Color& activatedColor,
                   bool alwaysDraw) :
    GUIObject(pos),
    m_defaultColor(defaultColor),
    m_activatedColor(activatedColor)
    {
        m_map[Button_Actions::CLICKED] = (thor::Action(sf::Mouse::Left, thor::Action::PressOnce));

        m_system.connect(Button_Actions::CLICKED, &Button::onClick);
    }

Running this will give me an error of:
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\functional|2013|error: no match for call to '(std::_Mem_fn<void (SE::Button::*)(thor::ActionContext<SE::Button::Button_Actions>)>) (const thor::ActionContext<SE::Button::Button_Actions>&)'|

It also opens up the functional file and points to an error on line 2013.
Current Projects:
Technoport