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

Pages: [1]
1
DotNet / Re: Suggestion: Make all structs immutable
« on: July 14, 2014, 07:13:49 pm »
Hm sorry, i didn't clarify it well.

Can initialization syntax be used to assign to something, that is not a property, but a regular field?
Yes, it can.

Is it usefull for immutable structs?
Sadly no. :(

You could still use reflection (either using Activator which is really slow, or compiled ExpressionTrees which is overkill) to assign to private fields without creating every possible constructor.  :-\

2
DotNet / Re: Suggestion: Make all structs immutable
« on: July 13, 2014, 03:04:51 pm »
That's not what i said.

3
DotNet / Re: Suggestion: Make all structs immutable
« on: July 13, 2014, 12:45:06 pm »
Quote
Because for you to use this syntax there is 2 requirements: what you are assigning is a property (not a plain old variable), and that the property can be assigned

This is plain wrong.

This works,
Code: [Select]
RenderStates r = new RenderStates { BlendMode = BlendMode.Add, Texture = new Texture(@"blah.png") };

while these being fields, NOT properties:

Code: [Select]
/// <summary>Blending mode</summary>
public BlendMode BlendMode;

/// <summary>Transform</summary>
public Transform Transform;

/// <summary>Texture</summary>
public Texture Texture;

/// <summary>Shader</summary>
public Shader Shader;

Quote
(and it won't if the struct is immutable as the property can't have a setter).

Of course it can.  :D

Code: [Select]
struct Foo
{
public Foo(int b)
{
boo = b;
}

private readonly int boo;
public int Boo
{
get { return boo; }
set { Console.WriteLine("I exist."); }
}
}

4
DotNet / Re: Suggestion: Make all structs immutable
« on: July 12, 2014, 01:35:08 pm »
Quote
You didn't answer the "huge number of constructors" argument, so I guess you also agree  ;)

Code: [Select]
RenderStates r = new RenderStates { BlendMode = BlendMode.Add, Texture = new Texture(@"blah.png") };

You don't need to add any new ctor overload, if you use initalization syntax. :)


Well, I guess, keep it as it is.

5
DotNet / Re: Suggestion: Make all structs immutable
« on: July 12, 2014, 10:07:21 am »
@Laurent: The thing that properties add compared to fields are mainly better encapsulation and changes to Vertex would never be breaking code on the consumer side, since you can just modify what the property does.

Well, i did some performance testing. Obviously the immutable Vertex is slower by longitudes.

On Ideone (scroll to the very bottom for result times) it ran about 3 times slower, however on my machine (SFML 2.1, VS 2010 Ultimate, X86 Release Build) it ran slower by a factor of 35. :(

Now i think i am no longer willing to sacrifice THAT much performance for having immutable value types.
Maybe some good practices and business rules don't apply to graphic libs.

6
DotNet / Re: Suggestion: Make all structs immutable
« on: July 10, 2014, 11:01:55 pm »


/// <summary>
/// Define a point with color and texture coordinates
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct Vertex
{
        /// <summary>
        /// Construct the vertex from its position
        /// The vertex color is white and texture coordinates are (0, 0).
        /// </summary>
        /// <param name="position">Vertex position</param>
        public Vertex(Vector2f position) :
                this(position, Color.White, new Vector2f(0, 0))
        {
        }

        /// <summary>
        /// Construct the vertex from its position and color
        /// The texture coordinates are (0, 0).
        /// </summary>
        /// <param name="position">Vertex position</param>
        /// <param name="color">Vertex color</param>
        public Vertex(Vector2f position, Color color) :
                this(position, color, new Vector2f(0, 0))
        {
        }

        /// <summary>
        /// Construct the vertex from its position and texture coordinates
        /// The vertex color is white.
        /// </summary>
        /// <param name="position">Vertex position</param>
        /// <param name="texCoords">Vertex texture coordinates</param>
        public Vertex(Vector2f position, Vector2f texCoords) :
                this(position, Color.White, texCoords)
        {
        }

        /// <summary>
        /// Construct the vertex from its position, color and texture coordinates
        /// </summary>
        /// <param name="position">Vertex position</param>
        /// <param name="color">Vertex color</param>
        /// <param name="texCoords">Vertex texture coordinates</param>
        public Vertex(Vector2f position, Color color, Vector2f texCoords)
        {
                this.position = position;
                this.color = color;
                this.texCoords = texCoords;
        }

        /// <summary>
        /// Provide a string describing the object
        /// </summary>
        /// <returns>String description of the object</returns>
        public override string ToString()
        {
                return "[Vertex]" +
                                " Position(" + Position + ")" +
                                " Color(" + Color + ")" +
                                " TexCoords(" + TexCoords + ")";
        }

        /// <summary>2D position of the vertex</summary>
        public Vector2f Position { get { return Position; } }
        private readonly Vector2f position;

        /// <summary>Color of the vertex</summary>
        public Color Color { get { return color; } }
        private readonly Color color;

        /// <summary>Coordinates of the texture's pixel to map to the vertex</summary>
        public Vector2f TexCoords { get { return texCoords; } }
        private readonly Vector2f texCoords;
}



class Program
{
        static void Main(string[] args)
        {
                // oops, accidently called default ctor on immutable struct
                Vertex badVertex = new Vertex();
                // notice at compile time
                Console.WriteLine(badVertex);
                badVertex.Color = Color.Red;
                Console.WriteLine(badVertex);

                // hey, thats fine.
                Vertex vertex = new Vertex(new Vector2f(50, 50), Color.Black);
        }
}
 

The advantages were mentioned, as suggested by Eric Lippert, Microsoft, and every serious book on topic. A value type should just be used as a container to represent values, that are not changable in any way.

I am not willing to get into a flame war with you, zsbzsb.

It was a suggestion.

If you don't like it, don't do it.
If you like it, do it.
If you are unsure, use that well-known search engine what the developers of the C# language and CLR's take is on this issue.


7
Graphics / Re: Graphic issue with vertical / horizontal lines
« on: July 10, 2014, 10:05:03 pm »
Quote
First, this 0.375 offset was an OpenGL-related fix that concerned a very old SFML version. That post was from 2009, which is half a decade ago.

It doesn't automatically mean, it is fixed now, does it? :)

Thanks for the additional link to the link to that commit. I have removed the +0.375, +0.375 offset and are now just truncating everything.

EDIT: I forgot to mention: The problem still consists!  :D

public void DrawState()
{
        if (window.IsOpen())
        {
                window.DispatchEvents();
                window.Clear(clearColor);

                // draw map + player
                zoomableView.Center = new Vector2f(
                        (int)(player.Position.X + (Config.PlayerSize.X >> 1)),
                        (int)(player.Position.Y + (Config.PlayerSize.Y >> 1)));

                GfxUtils.CheckValid(zoomableView);
                window.SetView(zoomableView);
                EntityManager.Instance.Draw(window, rs);
                window.SetView(window.DefaultView);

                window.Display();
        }
}

// called before drawing every entity (mob, player, tile)
public static void CheckValid(Transformable t)
{
        bool isValid = t.Position.X == (int)t.Position.X;
        isValid &= t.Position.Y == (int)t.Position.Y;
        isValid &= t.Origin.X == (int)t.Origin.X;
        isValid &= t.Origin.Y == (int)t.Origin.Y;
        isValid &= t.Scale.X == (int)t.Scale.X;
        isValid &= t.Scale.Y == (int)t.Scale.Y;
        isValid &= t.Rotation == (int)t.Rotation;
        isValid &= (int)t.Rotation % 90 == 0;
        if (!isValid)
        {
                Program.Logger.Error(new InvalidOperationException(t.ToString()));
                System.Diagnostics.Debugger.Break();
        }
}

// called before drawing any view
public static void CheckValid(View v)
{
        bool isValid = v.Center.X == (int)v.Center.X;
        isValid &= v.Center.Y == (int)v.Center.Y;
        isValid &= v.Rotation == (int)v.Rotation;
        isValid &= v.Rotation % 90f == 0;
        isValid &= v.Size.X == (int)v.Size.X;
        isValid &= v.Viewport.TopLeft.X == (int)v.Viewport.TopLeft.X;
        isValid &= v.Viewport.TopLeft.Y == (int)v.Viewport.TopLeft.Y;
        isValid &= v.Viewport.TopRight.X == (int)v.Viewport.TopRight.X;
        isValid &= v.Viewport.TopRight.Y == (int)v.Viewport.TopRight.Y;
        isValid &= v.Viewport.BottomLeft.X == (int)v.Viewport.BottomLeft.X;
        isValid &= v.Viewport.BottomLeft.Y == (int)v.Viewport.BottomLeft.Y;
        isValid &= v.Viewport.BottomRight.X == (int)v.Viewport.BottomRight.X;
        isValid &= v.Viewport.BottomRight.Y == (int)v.Viewport.BottomRight.Y;
        if (!isValid)
        {
                Program.Logger.Error(new InvalidOperationException(v.ToString()));
                System.Diagnostics.Debugger.Break();
        }
}
 

8
DotNet / Re: Suggestion: Make all structs immutable
« on: July 10, 2014, 08:55:42 pm »
Quote
This will break lots of existing code and cause more issues than the two we already have.

To me, this is the only valid objection, as this is - of course - a breaking change.

Quote
not to mention any decent C# dev will know that modifying value types that have been copied into methods won't change it outside of the method. Or a quick google search will bring this up.

This logic perplexes me. So, if any "decent dev knows" / "it is easy to google for" how 'abc' works, so why not keep forcing the user to use 'def' instead, which is tons more error-prone.

Quote
How so? It doesn't force them to use the non-default constructor and all non-default constructors initialize everything with default values.

Look for example as the link why got me to create this post at the very top. :) It _is_ easy to overlook.

Edit: removed links to constructor chaining and intialization syntax, since zsbzsb was talking about time of creation of the type. My bad.

Quote
Making structs immutable will require us to now provide every single possible constructor
Just think of vectors, to change a vector's value you will now need to create a new vector every single time you want to modify it instead of just changing the existing value.

Thats were Properties in C# come in.

The majority of books on this subject suggest to implement _all_ public members (with exception for public static or read-only value types or ReadOnlyCollections) as Properties.
Not only will they allow total control of access on the underlaying value, also modifying the logic when accessing its value will never be a breaking change for existing code.

And you don't need to worry for performance either. ValueTypes are extremely light-weight, and if used locally they are created on the stack even. Now will replacing the fields by properties be a performance drawback in Release builds, since the properties will be inlined.

9
DotNet / A few small suggestions
« on: July 10, 2014, 08:28:46 pm »
A few small things that i would like to suggest are:

1.
Instead of having the users override Destroy() of ObjectBase to handle finalizing, let users implement the IDisposable interface and use the standard suggested finalizer.

This used to crash at a decent chance, when i just assigning a new AnimatedSprite to the old variable:

class AnimatedSprite : Sprite, IUpdateable, ICloneable, IDisposable
{
        bool disposed = false;

        public void Dispose()
        {
                Dispose(true);
                GC.SuppressFinalize(this);
        }

        void Dispose(bool disposing)
        {
                if (!this.disposed)
                {
                        if (disposing)
                        {
                                // dispose managed ressources
                                EntityManager.Instance.UnregisterDrawable(this);
                                EntityManager.Instance.UnregisterUpdateable(this);
                        }
                        // dispose unmanaged ressources
                }
        }

        ~AnimatedSprite()
        {
                Dispose(false);
        }
}
 

Access violations when i created a new instance of AnimatedSprite, although i handled disposing myself, until i found out i was supposed to overwrite Objectbase.Dispose() (using an almost empty override just to stop the garbage collector from finalizing the sprite, while sfml was still drawing the object).


2.
Remove the /////////////////////////////////////////////// first and last line of the xml doc tags.
Common IDEs such as Visual Studio and MonoDevelop will not display tooltips (i.e. IntelliSense), since they don't understand xml docu that way. (Also documentation compilers such as SandCastle will not be able to create a documentation that way)

3.
- Add explicit conversions for closely related types, such as Vector2f, Vector2i, Vector2u, e.g.

        public static explicit operator Vector2f(Vector2i vector)
        {
                return new Vector2f(vector.X, vector.Y);
        }
 

- Add extension methods for closely related types, such as Vector2f, Vector2i, Vector2u, e.g.

        public static class VectorExtensions
        {
                public static Vector2i ToVec2i(this Vector2f vec)
                {
                        return new Vector2i((int)vec.X, (int)vec.Y);
                }

                public static Vector2u ToVec2u(this     Vector2f vec)
                {
                        return new Vector2u((uint)vec.X, (uint)vec.Y);
                }

                public static Vector2f ToVec2f(this Vector2i vec)
                {
                        return new Vector2f(vec.X, vec.Y);
                }

                public static Vector2u ToVec2u(this Vector2i vec)
                {
                        return new Vector2u((uint)vec.X, (uint)vec.Y);
                }

                public static Vector2f ToVec2f(this Vector2u vec)
                {
                        return new Vector2f(vec.X, vec.Y);
                }

                public static Vector2f ToVec2i(this Vector2u vec)
                {
                        return new Vector2f(vec.X, vec.Y);
                }
        }
 

allowing for a bit more comfort:

static void Main(string[] args)
{
        Vector2f vec2f = new Vector2f(50f, 100f);
        Vector2u displayResolution = vec2f.ToVec2u();

        Vector2i vec2i = new Vector2i(50, 100);
        Vector2f someVec2f = (Vector2f)vec2i;
}
 

10
Graphics / Re: 2d scaling, pixel size vs. gameworld size
« on: July 10, 2014, 07:47:16 pm »
I have opened a new thread with that suggestion on the .net subforum, see here:)

Also it would not really make developers life harder, if you instead turn the fields into properties, and have the setter return a new instance of the modified struct. You might also use extension methods instead, or offer both versions to the users. :)

11
DotNet / Suggestion: Make all structs immutable
« on: July 10, 2014, 07:42:29 pm »
Related to this topic I want to suggest to make all structs immutable.

- With mutable structs it is extremely easy to loss data, when e.g. users accidently modify a copy of a struct instead of the structs
- Immutable structs are automatically thread safe by nature
- Users will no longer forget to initialize some of the fields
- There would be almost no performance penalty, as structs (unlike as in Java) are extremely light-weight objects

For reference:
Microsoft Advice on Struct Design

Burning monk on structs

Eric Lippert (Designer of the C# language and the CLR) about mutable structs

Eric Lippert - value types may be created on the stack (extremely light-weight to create)


12
Graphics / Re: 2d scaling, pixel size vs. gameworld size
« on: July 10, 2014, 12:03:04 am »
Hello lid6j86.

This behaviour is a result of a somewhat poor design choice, of not implementing all structs as immutables in the .net bindings version of SFML. You want to only allow setting field values of value types during construction, either via using a parameterized constructor, or the initialization syntax, e.g.

var vertex = new Vertex { Position = new Vector2f(50, 50) };

It was correctly done with for example the operator overloads of Vertex2f, but not its fields. As a result, people will call the implicit default constructor and forget to assign values to some of the fields.

In your example, when you created a new Vertex using the default (non explicit) constructor, the color was intialized with rgba values (0, 0, 0, 0).

vArray[0].Position = new Vector2f(0, 0);
vArray[0].TexCoords = new Vector2f(0, 0);
vArray[0].Color = new Color(255, 255, 255, 255);   //fine

If all value types would have only read only fields, you would not be able forget to set any of its fields, so it is intialized with the default value of the type of the field. (Or, if you use the initialization syntax with curly brackets, your IDE will probably display all fields and you will not forget to assign a value to the color )

13
Graphics / Re: Graphic issue with vertical / horizontal lines
« on: July 09, 2014, 08:44:12 pm »
Hi zsbzsb. Thanks for your reply.

I think i tried almost all tricks now, been on this for ages. Now i am doing the following before drawing:

- Position of the player is rounded. (I should remove this, since the position of the camera, that is centered around the player, is also rounded before drawing)
- Center of the view is set rounded(player position + half its size).
- Positions of all entities (mobs, tiles) are rounded, then vec2f (0.375, 0.375) is added to their position.
  Since those are drawn relative to the camera, they should have 0.375 offset.

This is pixel perfect, as long as i don't zoom in/out.

For zooming, i dont like use Zoom() as this zooms in/out relative to the currenct zoom level. E.g., if i zoom using Zoom(0.96f) i'd have to undo it setting Zoom(1/0.96f) which can not be represented as float (with finite mantisse :)) without introducing rounding error.

Instead of zooming from the default view, i am just setting the Size of the View. I am using a tweening lib for a smooth QuadInOut effect, and - again - rounding the Size vec. So all the entity boundaries should hit x.375, y.375 relative to the camera.

Still the issue consists.

Where do i go wrong with the zooming?

14
Graphics / Re: Graphic issue with vertical / horizontal lines
« on: July 08, 2014, 09:48:47 pm »
Hello Nexus. Thanks for your fast reply.

After reading throu about 8 or 9 topics regarding this issue, i found the most promising suggestion to

1.
Keep using floats for all object positions and before drawing anything, round it, then add +0.375f to its position

2.
Another popular solution seemed to be, to instead of using IntRects for the texture location, use the FloatRect with GL texture coordinates 0.0 - 1.0 and substract 0.5 / subrect size from bottom right corner. e.g. if i am using a texture atlas containing 8x8 artwork, it was suggested to use 1.0 - 0.0625 = 0.9375 at the bottom right corner of the texture float rect

Unfortunately using the 1st suggestion does not seem to help.
I tried "round positions" and "round view, add 0.375, 0.375" to the view, no difference, and then
"round positions, add 0.375, 0.375" to all positions and the view, still no change.

Trying the 2nd approach i tried instead using a different texture rect. Unfortunately using the .NET version of SFML does not seem to provide an ctor overload to use FloatRect for the Texture coordinates. In another post from you (see here) i have read that you use gl translate just on all the drawables (but not on the view?). Unless i additionally use Tao or OpenTk there seems to be no way to directly use OpenGL.

Or translating the Drawable by 0.375, 0.375 already done in the external c lib, so i am doing it twice now actually?

Hmm.

15
Graphics / Graphic issue with vertical / horizontal lines
« on: July 08, 2014, 07:29:53 pm »
Hello everyone. I am currently on working a small game using the SFML .NET V2.1 bindings and i am encountering some kind of graphic glitch on some machines.

This is what the game currently looks on my desktop:



I have sent someone a copy to try it out on another machine, this is what the game looks for him:







Edit: Added this shot. Vertical line right beside the player sprite and horizontal line above the whole image.



Old Version:



Notice the vertical lines.

I tried rounding down object coordinates to int of my tiles before drawing, various graphic settings including anti-aliasing (makes it a LOT worse), texture filtering (i love the current pixelated look), vsync and what not.

I encountered a similiar issue when creating the initial version of this game, using the slick library for java, before i moved to start over using .NET. Last time i fixed it, by using only floats during all calculations and finally truncating all images to int's immediatly when drawing them.

Does anyone have a suggestion, that i could try?

Pages: [1]