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

Author Topic: [Solved]Transform... a class? or maybe an struct?  (Read 13333 times)

0 Members and 1 Guest are viewing this topic.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Transform... a class? or maybe an struct?
« Reply #15 on: May 10, 2012, 08:17:28 am »
Yep, I'll try to do the modification as soon as I can :)
Laurent Gomila - SFML developer

NinjaFighter

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
    • http://www.sebagames.wordpress.com
Re: Transform... a class? or maybe an struct?
« Reply #16 on: May 10, 2012, 09:21:12 pm »
thank you so much! :D

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Transform... a class? or maybe an struct?
« Reply #17 on: May 11, 2012, 02:58:54 pm »
Structures cannot inherit from abstract classes, and they cannot have a default constructor. Unfortunately, Transform needs both :-\

Would you have solutions to suggest?
Laurent Gomila - SFML developer

Gonzilla

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Transform... a class? or maybe an struct?
« Reply #18 on: May 11, 2012, 03:25:08 pm »
Structures can only inherit from interfaces and by default they have a internal constructor that initialize the members to their default value.

public struct DemoStruct
{
    private Vector2f Position;
}

DemoStruct demo = new DemoStruct();
//demo.Position is {[Vector2f] X(0) Y(0)}

Constructor with parameters:
public struct DemoStruct
{
    private Vector2f Position;

    public DemoStruct(Vector2f position) :this()
    {
        Position = position;
    }
}

NinjaFighter

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
    • http://www.sebagames.wordpress.com
Re: Transform... a class? or maybe an struct?
« Reply #19 on: May 11, 2012, 09:14:43 pm »
I figured your problem, and I think the best way, is the way that XNA's matrices does.

The XNA's Matrix structure, doesn't have an array member, so, instead, they used a lot of members... by this way, they avoid the default constructor issues.
I think is a best way to do not complicate a critical object, so, I think is good to not use inheritance with that structure.

I recommend you to make Matrix structure like XNA's does. This is a useful way and it has a very simple usage.
http://msdn.microsoft.com/en-us/library/bb197911

Edit:
In other words... I recommend you to make Matrix structure just like Vector structures are. Think about it: you don't use arrays with Vector3 for example, because there are only a few values and they have fixed size. So, Matrices are similar, there are only a few values, and they have fixed size too.
« Last Edit: May 11, 2012, 09:49:21 pm by NinjaFighter »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Transform... a class? or maybe an struct?
« Reply #20 on: May 11, 2012, 10:41:20 pm »
But there's a big difference between Transform and Vector2: Transform is a wrapper around a C API object (so it has to inherit from the ObjectBase class, and have a default constructor) while Vector2 is just a plain struct which is passed directly as it is to the C API. Don't forget that SFML.Net is a binding, I'm not free to implement things like I want.

Vector2 can be handled like this because it's a very light and simple structure, it can be converted to sf::Vector2f in every function call in the C API. Transform is heavier with its 9 float members and its functions. It would be inefficient if I handled it differently.
Laurent Gomila - SFML developer

NinjaFighter

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
    • http://www.sebagames.wordpress.com
Re: Transform... a class? or maybe an struct?
« Reply #21 on: May 11, 2012, 11:04:20 pm »
Ok, then... you can add an overload to the functions that receive a Transformation, and make them capable to receive a sequence of floats too. Then, (internally,) you can use a new C transformation, created with received parameters. So, you can use a new Transform implementation, that can be a new C# struct.
I'm explaining right?

NinjaFighter

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
    • http://www.sebagames.wordpress.com
Re: Transform... a class? or maybe an struct?
« Reply #22 on: May 11, 2012, 11:27:23 pm »
hmmm... What if you implement a function "SetMatrix(float[] aValues)" on your actual Transformation class?

You can do something like that:
Code: [Select]
//Basic DisplayObjects hierarchy
float[] parentTransform = mySprite.Transform.GetMatrix();
float[] childTransform;

foreach(Sprite child in mySpriteChilds){
   childTransform = MyHelper.MultplyMatrixValues(parentTransform, child.Transform);
   
   mySingleOneTransform.SetMatrix(childTransform);
   //TODO: Draw child with childTransform
}

It's a bit more complex that struct's way, but at least you can continue using your Transform class.

Edit:
Whatever... I think the best way still can be to use another Transform struct (without bind to C Transform), and bind it only when you set a Transform by parameter.
Maybe, could be inefficient if you copy matrices every time when you set a transformation, but think about it... there are only 16 floats by matrix, this could be trivial process time, but if you use and instantiate new classes instead, not only is copying all the values, also is creating garbage (several times usually) by a single render call.  :-\
I think is crucial to make this a new structure and hide the original C Transform object to C#... no matter if you lose a little performance copying 16 floats every time that a Transform has been used, note that every time that you returns a new Transform, you are copying all values again and make a new instance of a class, I'm sure this is more slow than copy 16 floats to a C object one by one.
Correct me if I'm wrong, I never make a C# binding, and is possible that I'm ignoring something.
« Last Edit: May 12, 2012, 06:05:00 am by NinjaFighter »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Transform... a class? or maybe an struct?
« Reply #23 on: May 12, 2012, 09:57:48 am »
Copying 16 floats is not what I'm worried about. My main concern is to avoid allocating/destroying a Transform object on the heap every time a C function that takes a Transform argument is called.

And if I don't use the sfTransform C structure directly, I will have to duplicate its code. It's not very complicated, but it's definitely harder to maintain and more error-prone.

But I'm not giving up, I'll try to find a solution >:(
Laurent Gomila - SFML developer

NinjaFighter

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
    • http://www.sebagames.wordpress.com
Re: Transform... a class? or maybe an struct?
« Reply #24 on: May 12, 2012, 11:42:19 am »
With a "SetValues" method, capable to set all matrix values (just like Transform's constructor does (apparently)), you can easily avoid the Transform class creation. You can let Transform to be a class too by this way. If you have a RenderTarget method that receive a Transform (for example) you can set the same values that the argumented Transform (without do modifications on it), and the user can do all Transformations with one single instance (if he wants). Personally, if Transform is a class, capable to copy the internal data without need to duplicate instances... could be ok for me, because I can write my own Matrix structure and write methods to set his values on a SFML Transformation instance.

Obviously, the more elegant way would be a Transform struct, but I understand that may be complicated.

Inverness

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Transform... a class? or maybe an struct?
« Reply #25 on: May 19, 2012, 12:55:36 am »
I'd like to chip in and say that I just recently started using SFML.NET and was surprised to find that Transform is a class and not a struct. Having to allocate an object on the heap every frame is bad. The Transform class needs to be made a struct and modeled after the Matrix class in XNA that uses static functions to modify matrices by reference and avoid copying them. (i.e.: Matrix.Add(ref Matrix a, ref Matrix b, out Matrix c)) It should not be a wrapper around a C object, since keeping it as a struct in C# allows for better optimization for operations in C#.

In my opinion, simply make the underlying API take a reference to the Transform struct and then let it do whatever it wants with that.

Also, chain calls are nice fluff, but they're ultimately fluff and having performance is what matters in this case. I can deal with the loss of chain calls if it means not having 60+ heap allocations every second while idle.
« Last Edit: May 19, 2012, 01:02:21 am by Inverness »

NinjaFighter

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
    • http://www.sebagames.wordpress.com
Re: Transform... a class? or maybe an struct?
« Reply #26 on: May 19, 2012, 03:40:30 am »
I'm agree with you.
There are any news about this, Laurent?

I think a Transformation struct can be unique for DotNet Binding, and change the parameter that other objects can receive. I think that in this case, is justifiable.

I want to pass my gameengine implementation to the SFML2 RC, but I'm currently waiting for this change  ;D

Inverness

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Transform... a class? or maybe an struct?
« Reply #27 on: May 19, 2012, 04:30:14 am »
I have no real experience with DllImport in C#, but you should be able to create a struct class in C#, then pass it to your C/C++ code as MyFunc(ref MyStruct myStruct), which I assume would give you a pointer in C/C++, which you could cast to your equivalent C/C++ struct. This means you'd need your C# struct to have the same members and alignment as the C/C++ struct, but that should be simple enough.

Edit: Here is an article explaining the details: http://msdn.microsoft.com/en-us/library/awbckfbz.aspx
« Last Edit: May 19, 2012, 04:32:34 am by Inverness »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Transform... a class? or maybe an struct?
« Reply #28 on: May 19, 2012, 08:02:34 am »
I know how it works, I already do that with other structures ;)

But CSFML is a binding too, so there's no Transform structure in it, only a wrapper around a C++ sf::Transform pointer. So I would have to do the same modification in CSFML, which means duplicating the Transform functions three times. Definitely not the best thing to maintain.
Laurent Gomila - SFML developer

NinjaFighter

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
    • http://www.sebagames.wordpress.com
Re: Transform... a class? or maybe an struct?
« Reply #29 on: May 19, 2012, 09:49:29 am »
Please, if you don't want to make a Transform structure, consider to implement another way to set the transformations in render, maybe passing an entire matrix instead a Transformation instance. I think this is critical, really, My hands refuse to typing code that instantiate classes during render.  :P

For the specific case of a displayobject hierarchy, it's more easy to make a GetValues and SetValues methods in your current Transform class. Please, make one of these changes if you does not figure a better way  :)