SFML community forums
Bindings - other languages => DotNet => Topic started by: zsbzsb on April 22, 2014, 03:21:17 am
-
I talked to Laurent about updating SFML.NET and making some changes. He suggested I post a list of proposed changes so we can discuss them before I start making pull requests. If anyone has any suggestions or ideas please post them here.
Project Files
Add project files that match VS 2010, VS 2012, and VS 2013 - instead look at a possible meta-build system
SFML.Window
- Explicit vector casting (PR #28 (https://github.com/SFML/SFML.Net/pulls/28)) - fixed
- Define Equals() overrides for vectors - fixed
SFML.Graphics
- Color == and != comparision (PR #29 (https://github.com/SFML/SFML.Net/pulls/29)) - fixed
- Window.IsOpen() should be a property (Issue #23 (https://github.com/SFML/SFML.Net/issues/23)) - fixed
- Shape.GetPointCount() and Shape.SetPointCount() should be a property [including classes derived from Shape] - needs to be discussed
Add indexed property for Shape points - and then possibly remove Shape.GetPoint() and Shape.SetPoint() [including classes derived from Shape] - decided againstAdd indexed property for Image pixels - and possibly remove Image.GetPixel() and Image.SetPixel() - decided against- RenderTarget.GetView() and RenderTarget.SetView() should be a property [including derived classes] - should be discussed
- RenderWindow.InternalSetMousePosition() and RenderWindow.InternalGetMousePosition() should be removed - fixed
- VertexArray.GetBounds() should be a property - fixed
- Transform.ToString() produces wrong results (Issue #34 (https://github.com/SFML/SFML.Net/issues/34)) - fixed
- Investigate Issue #5 (https://github.com/SFML/SFML.Net/issues/5)
- Investigate Issue #25 (https://github.com/SFML/SFML.Net/issues/25)
- Investigate PR #23 (https://github.com/SFML/SFML.Net/pulls/23) - fixed
- CSFML and SFML.NET updates to match C++ version of SFML - see the end of this post (http://en.sfml-dev.org/forums/index.php?topic=15003.msg105942#msg105942) for full list
- OpenTK Support
SFML.System
- Add Time and Clock classes - yes the .NET/Mono framework provides System.Diagnostics.Stopwatch but it can not provide high resolution without conversion from the Ticks property and this can be cumbersome to use - done
- Move Vector2 struct to SFML.System (from SFML.Window) - done
- Move Vector3 struct to SFML.System (from SFML.Audio) - done
- Move ObjectBase to this module - done
- Add support for redirecting error output
-
I'd be happier with a networking class for both TCP and UDP making the existing .net ones easier to use. :)
-
Add support for OpenTK. Tao is from 2005! I've seen some old threads suggesting that it's possible to use OpenTK with SFML 1.6, but the solutions are all hacky and I've never been able to get it to work with 2.0.
In my opinion this is the biggest thing holding SFML.NET back.
-
I'll comment some of the points listed, you can consider the others validated.
Add project files that match VS 2010, VS 2012, and VS 2013
Why? It would make maintenance of project files 4 times longer. Anyone can convert the project files to his version of the IDE, as long as we provide projects in VS 2008 format (Visual Studio cannot do backward conversion).
What would be great is a meta-build system, like CMake for the C++ library. I don't know if such a system exists for .Net (and that would be compatible with the Mono IDEs).
Add indexed property for Shape points - and then possibly remove Shape.GetPoint() and Shape.SetPoint() [including classes derived from Shape]
Add indexed property for Image pixels - and possibly remove Image.GetPixel() and Image.SetPixel()
How would the new API look? Wouldn't it differ too much from the C++ API?
RenderWindow.InternalSetMousePosition() and RenderWindow.InternalGetMousePosition() are not used and should be removed
Really? I created them on purpose, I would be surprised if they were not used. But I remember that soon after I pushed this code, I found a less ugly way of doing it; and didn't came back to implement it.
When the blend modes branch gets merged to master update CSFML and SFML.NET
The commits in SFML since the last release should be reviewed, and any modification to the pubic API should be made into CSFML and SFML.Net too.
SFML.System
Hmm... are you really sure that the .Net SDK doesn't provide anything equivalent to the Time and Clock classes?
Providing an incomplete System module would be confusing (and I don't want to provide the threading classes).
I'd be happier with a networking class for both TCP and UDP making the existing .net ones easier to use.
The .Net framework already has everything that you need for manipulating TCP and UDP sockets.
Add support for OpenTK. Tao is from 2005!
True! :)
-
Why? It would make maintenance of project files 4 times longer. Anyone can convert the project files to his version of the IDE, as long as we provide projects in VS 2008 format (Visual Studio cannot do backward conversion).
True, I didn't think of that point. Its just slightly annoying to use the auto upgrade :P
What would be great is a meta-build system, like CMake for the C++ library. I don't know if such a system exists for .Net (and that would be compatible with the Mono IDEs).
There is some build systems out there, and if they can run on linux all Mono IDEs support the VS *.csproj format. I could take a closer look to see if any of them match what we are trying to do.
How would the new API look? Wouldn't it differ too much from the C++ API?
I'm not too sure on these changes, I was more or less thinking out loud. .NET/Mono framework conventions is to avoid writing getters and setters and instead use properties. However there is nothing wrong with using a getter/setter if you wish to be more expressive. An indexed property (http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx) is the same type of property that is implemented on the VertexArray class to give access to vertices. So it would look like the following.
using SFML.Graphics;var myshape
= new ConvexShape
();myshape
.PointCount = 4; // this would be a new property instead of SetPointCount()myshape
[0] = new Vector2f
(50
.0f, 100
.0f
); // and this would be the indexed property for points instead of SetPoint()
Really? I created them on purpose, I would be surprised if they were not used. But I remember that soon after I pushed this code, I found a less ugly way of doing it; and didn't came back to implement it.
Oops, I guess I failed on my search for any usage locations. They are currently used in a single location each and it would be trivial to refactor that usage out. On the plus note, there won't be a need for a public function that the documentation reads "warning: do not touch me!" :D
The commits in SFML since the last release should be reviewed, and any modification to the pubic API should be made into CSFML and SFML.Net too.
Yep, I forgot about some commits so I went through the commit log and at the end of this post you will find things that should make it into CSFML and SFML.NET.
Hmm... are you really sure that the .Net SDK doesn't provide anything equivalent to the Time and Clock classes?
There is a TimeSpan class, but it is neither high resolution or very accurate. The System.Timers namespace can only provide at best a resolution 15ms. And if the user uncaps the framerate above 60fps you will run into timing issues.
The only way to get a true high resolution timer in C# is with System.Diagnostics.Stopwatch. However this class only provides a way to measure time and return the value in ticks. So its left to the user to convert the ticks (based on the clock frequency) to whatever measurement of time they wish. This is the reason I implemented the Time and Clock classes in NetEXT as a way to provide easy measurement just like the C++ version of SFML does.
Providing an incomplete System module would be confusing (and I don't want to provide the threading classes).
I agree about it being confusing, but I think the current state is already slightly confusing. With the vector structs spread into the graphics and audio modules and no system module at all. About threading... isn't the plan to drop sf::Thread anyways and go with C++11 threading features?
With a system module we could also implement sf::err and also move the ObjectBase class into the system module. Instead of making the audio module depend on the window module for the base class.
I'd be happier with a networking class for both TCP and UDP making the existing .net ones easier to use.
As Laurent said, the .NET/Mono framework implementations are already much nicer and feature rich than what SFML provides. Not to mention the built in asynchronous functions [multithreading networking out of the box]. ;)
Add support for OpenTK.
Sounds like a good plan. :)
Here is the changes that SFML.NET and/or CSFML are behind on.
Audio capture device selection (https://github.com/SFML/SFML/commit/db77b76d91e3578f1678ef7acb42f887ecc59159)
Sound recorder processing interval (https://github.com/SFML/SFML/commit/b9d0295c89ec91a4e1cd8912c3a77fd4a87df28b) - CSFML fixed
Font info (https://github.com/SFML/SFML/commit/7caf2e64b6aa40c28367e736592c44976e58170f) - CSFML PR made
- operator for Color (https://github.com/SFML/SFML/commit/6d4c844959839c39b54412b924b5a2d15d3d577d) - fixed
Rect negative dimensions (https://github.com/SFML/SFML/commit/11837e9fc86a4ab35fb007035442bddefecf0217) - fixed
Up vector in the Listener class (https://github.com/SFML/SFML/commit/50e305277315a6af992e596cb20b2671b50ed775) - CSFML fixed
Joystick info - product id and vendor id (https://github.com/SFML/SFML/commit/29c0f1491177d9125cc731f0c04bdf4c21c4650e)
Documentation notes about coordinates and distorted rendering (https://github.com/SFML/SFML/commit/e074b6775e0bc5ed3e85bea3b1610d0e155d0a05) - fixed
Some documentation updates about the Shape classes (https://github.com/SFML/SFML/commit/e9243b7ef69083cce2fcb0651e45e42c1ea7adae) - fixed
Blend mode changes (https://github.com/SFML/SFML/commit/cdf32a78815eedbbed4fd9441c56842d283ce40b) - fixed
-
Most of these getter-to-property conversions sound reasonable. I am currently using the NetEXT timer classes for everything I need, so no protest against them. The biggest thing in the list for me was the inclusion of OpenTK. Great list Zachariah!
-Robert
-
I'm not too sure on these changes, I was more or less thinking out loud. .NET/Mono framework conventions is to avoid writing getters and setters and instead use properties. However there is nothing wrong with using a getter/setter if you wish to be more expressive. An indexed property is the same type of property that is implemented on the VertexArray class to give access to vertices.
Since this is also possible in C++, if it's not done in SFML, I'd say don't do it in SFML.Net ;)
I agree about it being confusing, but I think the current state is already slightly confusing. With the vector structs spread into the graphics and audio modules and no system module at all. About threading... isn't the plan to drop sf::Thread anyways and go with C++11 threading features?
With a system module we could also implement sf::err and also move the ObjectBase class into the system module. Instead of making the audio module depend on the window module for the base class.
Good points. So let's go with the System module :)
-
So these changes will be mostly around making our lives easier by using properties? Sounds nice :)
Btw IntRect, FloatRect and so are not related to graphics too imo, so why do not move them too to SFML.System?
-
Btw IntRect, FloatRect and so are not related to graphics too imo, so why do not move them too to SFML.System?
Well that would be something to bring up in a discussion about the actual SFML implementation (C++ version). And if that was to happen, it most likely wouldn't happen until SFML 3 due to the fact it breaks existing code.
http://sfml-dev.org/documentation/2.0/group__graphics.php (http://sfml-dev.org/documentation/2.0/group__graphics.php)
-
You're not the only one with this suggestion, it has already been discussed (http://en.sfml-dev.org/forums/index.php?topic=5644.0). Everybody seemed to agree at that time, so it's likely that sf::Rect will be moved to the System module in SFML 3 -- but not before, as zsbzsb says.
-
Everybody seemed to agree at that time
Are you sure? :P
-
You were hesitant, but in the end you didn't say anything against it anymore -- thus "seemed" :P but now that I read the thread again, I see that I completely missed Disch's answer.
Anyway, it would be discussed again, but I think until SFML 3 there are a few more important tasks ;)
-
Yep.
-
I'm glad that people are on board with OpenTK support!
Another thought - On Linux, XInitThreads from libX11 must be called for OpenGL windows to work properly. If possible this should happen in the background.
In general, better documentation of running SFML.NET on Mono is needed. Perhaps cross-platform versions of certain methods that differ between Mono and .NET could be added to the System module? For instance, on Mac and Linux System.Environment.ProcessorCount returns the number of physical processors, but on Windows it returns the number of logical processors.
-
I'm glad that people are on board with OpenTK support!
Another thought - On Linux, XInitThreads from libX11 must be called for OpenGL windows to work properly. If possible this should happen in the background.
In general, better documentation of running SFML.NET on Mono is needed.
Running SFML.NET on Mono? What more documentation do you need to do that? It is already childish simple :)
-
Sounds like you've never seen DllNotFoundException: csfml-window-2 ;)
It takes a bit of time to figure out where to put all the dependencies and how exactly to map the DLLs. On Linux editing the global DLL config is required for OpenGL support, on OS X I still don't fully understand how the native CSFML libraries are found, etc. That with platform differences in core .NET methods (edited last post) makes it more difficult that it needs to be.
-
Another thought - On Linux, XInitThreads from libX11 must be called for OpenGL windows to work properly. If possible this should happen in the background.
This issue will be solved after we switch to XCB, which is thread-safe.
It takes a bit of time to figure out where to put all the dependencies and how exactly to map the DLLs. On Linux editing the global DLL config is required for OpenGL support, on OS X I still don't fully understand how the native CSFML libraries are found, etc.
I'd be more than happy if someone could write a nice tutorial about it. I can't do it myself because I have no idea what needs to be done on these platforms ;D
-
Great!
I don't know if I'm the most knowledgeable person on the subject, but my stuff does run, so I could give it a shot. Will start a thread when I have some time.
-
This should be interesting to see. :)
-
Alright, time for a little recap. Several pull requests have been merged to fix some of the above issues. Check the original post for an updated list. However there are a few pull requests that need some additional discussion.
With the pull request (https://github.com/SFML/SFML.Net/pull/41) that changes GetPointCount() and SetPointCount() to a property a few things came up. The shape base class only defines the property with a getter and no setter. So in the circle and convex shapes we also need the setter. But in C# it is impossible to override a property and also add a setter if the base class does not define a setter. So there is 4 options to solve this.
#1 Instead of overriding the PointCount property in derived classes, simply declare the property as 'new'. This will allow the derived classes to implement getters or setters as needed, however it has the drawback of when a reference just to the base class type, any calls will not call the derived type's property. And then this breaks the inheritance model, so it is a nono from me.
#2 Go with how I setup the pull request, change GetPointCount to a property and then leave the function SetPointCount in the derived classes that allow changing the point count. The drawback here is that it is inconsistent. To get the point count the property is used, but to set a point count the function is used.
#3 Another option is built off of #1 and #2. Change both functions to a property and in the base shape class and just have the setter part of the function not do anything. This would allow derived classes to override the setters and/or getters without any issue and everything will work properly when dealing with base class types. The only drawback to this solution is that setting the point count may not have any affect and this may cause some confusion.
#4 Or leave as is with the functions for consistency.
With this pull request (https://github.com/SFML/SFML.Net/pull/39) I changed the SetView() and GetView() functions to a property. This issue with this is that we are wondering if it hides the true intent of of the View property. What I mean is that is it clear enough that you must set the view after changing it.
Take for example the following code.
// Current working codevar view
= window
.GetView();view
.Move(new Vector2f
(5,
5));window
.SetView(view
);// New property that would work// the question is whether or not this View property would be clear enough that you must assign it after changing itvar view
= window
.View;view
.Move(new Vector2f
(5,
5));window
.View = view
;// However I think both methods fall to this problemwindow
.GetView().Move(new Vector2f
(5,
5));window
.View.Move(new Vector2f
(5,
5));
Please give feedback on these issues. :)
-
#1: not a solution
#2: too inconsistent
#3: very bad design
so... to me the best one is still #4 ;)
Views: maybe we should find a totally different design. Obviously, C# doesn't provide the language features that makes this design work in C++ (no copy semantics, no read-only return types).
-
Views: maybe we should find a totally different design.
I was thinking about this, and with some internal trickery I think I could make the following work. In my humble opinion this option here would make the best sense. Sure it breaks consistency with the C++ version, but I think it makes some of the most sense.
No need to reassign the view, whatever changes you make on the view object automatically get applied back to the render target from where they came. Note that the daisy chaining would be optional.
window
.View.Move(new Vector2f
(5,
5)).Rotate(45);
-
And... how do you make this work?
-
Internally both the View/RenderWindow objects would track the which RenderWindow(s)/View(s) that are assigned to them.
Whenever the user grabs another View object from the RenderWindow, the View will have an internal reference to the RenderWindow and also the RenderWindow will keep a reference to the View. Then whenever that view is changed it will automatically apply those changes back to the internal reference. The same would apply to the RenderWindow, if it has its view reset to another view then it can go to all the internal references of each view that is assigned to it and remove its reference from those views.
If you want, I could come up with a more robust sample code to explain how the API and internally it would work.
-
Being able to have a list of views that auto update if you change something about them rather than having to go through the setting a new view over and over again for each when a change is made would be nice. :D That aside nothing to complain about too much. :)
-
Being able to modify Vertices in VertexArrays like you can in the C++ version would be awesome. It's tough to make good performing custom graphic types that rely on vertex arrays since in C# you have to create all new vertices or rebuild the geometry from scratch whenever an update is needed.
-
Being able to modify Vertices in VertexArrays like you can in the C++ version would be awesome.
Thing is, initializing a new vertex every time something changes is the best way to do it unless we broke conventions that would directly modify the underlying vertex array. structs in C# are value (meaning copied around by value) objects and are the easiest way to work with unmanaged memory. So this really won't be changing - however I have never seen any serious performance issues using SFML.NET compared to pure native C++ code. Just remember if you need to update your array just change the vertices that need to be changed. ;)
-
Internally both the View/RenderWindow objects would track the which RenderWindow(s)/View(s) that are assigned to them.
Whenever the user grabs another View object from the RenderWindow, the View will have an internal reference to the RenderWindow and also the RenderWindow will keep a reference to the View. Then whenever that view is changed it will automatically apply those changes back to the internal reference. The same would apply to the RenderWindow, if it has its view reset to another view then it can go to all the internal references of each view that is assigned to it and remove its reference from those views.
If you want, I could come up with a more robust sample code to explain how the API and internally it would work.
It can be done in this way, or in simplier way. You will have property View in RenderWindow. When you will change this view, in Draw call it will check equality between sfGetView and View what you have in RenderWindow, and if they are not equal, it will set View to RenderWindow. I think this won´t cause performance drop, but I am not 100% sure about it. There is also another method, and that is similar to Transformable class, so view will have internal boolean NeedsUpdate, what will change to true if you will change any property in View. And when RenderWindow sees that View needs update and uses this view, it will change its NeedsUpdate to false.
-
Someone to fix this?
http://en.sfml-dev.org/forums/index.php?topic=15343.0
(and possible similar errors in other Equals functions -- didn't check)
-
Alright, So I made a commit (https://github.com/zsbzsb/SFML.Net/commit/4b3208c1d1f4a48eaccd72f594066c4aa3d67c1f) that adds the System module (moves vectors and object base there for now), yet Github is screwing up and throwing an error 500 page so I can't make a PR :-[
Well after contacting github support they pushed a fix out for it so I made the pull request (https://github.com/SFML/SFML.Net/pull/61) now.
Sorry for the trouble! The team is investigating and I'll let you know when this is resolved.
Just wanted to followup and let you know that the team pushed out a fix for these 500s so things should be back to normal.
Anyways, I was thinking about how to do the Clock / Time classes. I could either use the built in Stopwatch class to provide the actual time measurement (how I did it in NetEXT) or I could do it like the rest of the binding and use the native Clock and Time classes. Let me know if anyone has any suggestions, but I am leaning towards using SFML's native classes for implementing the classes.
-
It's a binding, so use the C API. I thought you wanted the system module because the native classes were not equivalent? :P
-
It's a binding, so use the C API. I thought you wanted the system module because the native classes were not equivalent? :P
Native classes are not equivalent, that is true. I was talking about the implementation, we could use the C API to implement it (preferred) or implement it using the native System.Diagnostics.Stopwatch class as the internal implementation. The native class provides no easy way to convert the Stopwatch.Ticks property to milliseconds/seconds/minutes as it also relies on the Stopwatch.Frequency property.
Update
I have now made a PR (https://github.com/SFML/SFML.Net/pull/62) that implements the Time and Clock classes. I went with using the C API as the internal implementation to stay consistent with the rest of the binding.
-
I have been always using watch.Elapsed.TotalSeconds. Isn't it accurate enough?
-
I have been always using watch.Elapsed.TotalSeconds. Isn't it accurate enough?
Stopwatch.Elapsed returns a (http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.elapsed.aspx) returns a TimeSpan (http://msdn.microsoft.com/en-us/library/system.timespan.aspx) that uses different ticks ratio that is less accurate than directly using the Stopwatch.ElapsedTicks (http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.elapsedticks.aspx) property. Stopwatch ticks are tied to the hardware / platform so you will always get the highest precision available on the running platform.
http://geekswithblogs.net/BlackRabbitCoder/archive/2012/01/12/c.net-little-pitfalls-stopwatch-ticks-are-not-timespan-ticks.aspx
-
Thanks for the info. In this case, I would just write sw.ElapsedTicks / (float)Stopwatch.Frequency or have extension method for this.
-
Thanks for the info. In this case, I would just write sw.ElapsedTicks / (float)Stopwatch.Frequency or have extension method for this.
Or download the latest source from the SFML.NET repository as the Time and Clock classes have now been merged. :D
-
I'm happy to see this port being pushed forward. ;D
-
I just noticed the Visual Basic example is not up to date (it's drawing text without a font, not using the Time / Clock classes, etc.). Anyone? ;)
-
Let me download VB.NET Express 2008 and I will have a go at it. :)
However, the better question should be - do we really still need a VB.NET example? I mean the language everyone really only seriously uses with .NET/Mono is C# and any VB.NET programmer will be accustomed to converting C# examples to VB.NET. There is even several good and free online converters that will do the work for you. Not to mention, I don't think we have received even one person saying that it is out of date (and it is written using SFML 1.6). I think its obvious what I think we should do, but it is up to you Laurent - so for now I will update it.
-
You're right, but since it exists, let's keep it. It's also useful as a compatibility test case for us.
-
I don't know if this has been suggested yet but I think implementing IList (http://msdn.microsoft.com/en-us/library/system.collections.ilist(v=vs.110).aspx) and IList<T> (http://msdn.microsoft.com/en-us/library/5y536ey6(v=vs.110).aspx) interfaces for VertexArray would be very useful. With them implemented you could use foreach and LINQ + you get bunch of useful methods. Because VertexArray already has bunch of similar methods it would be wisest to implement the interfaces explicitly.
Now that I think about it, you could probably implement them for Shape too.
-
don't know if this has been suggested yet but I think implementing IList and IList<T> interfaces for VertexArray would be very useful. With them implemented you could use foreach and LINQ + you get bunch of useful methods.
Isn't it rather IEnumerable<T>?
-
I don't know if this has been suggested yet but I think implementing IList and IList<T> interfaces for VertexArray would be very useful.
That wouldn't really be feasible, first it would require implementing methods that even the core SFML doesn't support for the vertex array. And second, there is no smart way to implement Insert(...) and RemoveAt(...) functions. It would just be a big complicated copy operation.
Now that I think about it, you could probably implement them for Shape too.
We already decided that we need the existing design to make it clear the intention of the Shape classes.
Isn't it rather IEnumerable<T>?
It is, so if we want the foreach syntax for the vertex array we could implement this instead of trying to implement other interfaces that don't make sense.
-
Isn't it rather IEnumerable<T>?
It is, so if we want the foreach syntax for the vertex array we could implement this instead of trying to implement other interfaces that don't make sense.
This would be okay. IEnumerable<T> gives most of the useful stuff anyway.
-
Note that VertexArray is slow due to P/Invoke. Maybe we should just reimplement entire thing as a subclass of List<T>.
-
Note that VertexArray is slow due to P/Invoke.
Its slow how? In my experience it is just as fast as the native implementation.
Maybe we should just reimplement entire thing as a subclass of List<T>.
And this would help how?
-
Nevermind. I checked and setting points is only like 2x slower on VertexArray. I was expecting order of magnitude slower.