2020-09-27

Set value of a property after constructor without calling additional method

public class Button {
    private Tuple<int, int> _transformed;

    public int X { get; set; }
    public int Y { get; set; }

    public Button() {
        _transformed = Util.Transform(X, Y, Align.Center);
    }

    public void Display() {
        // Example methods to display button's elements
        // DrawBorder(_transformed ...)
        // DrawBackground(_transformed ...)
        // DrawButtonText(_transformed, ...)
    }
}

public class GUI {
    private Button _button;

    public GUI() {
        _button = new Button( ) {
            X = 64,
            Y = 64
        };
    }

    public void DisplayGUI() {
        _button.Display( );
    }
}

Let's assume that we've got a static method Transform that transforms X and Y according to the given alignment, eg. Align.Center. We'll keep the result inside a _transformed field.

Problem

In short: I want to set the value of a field/property with a result of the external method that uses values of other properties inside the same class, automatically after creation of an instance, without calling additional methods or workarounds

My goal is to create generic Button class in which you can assign multiple properties (like in CSS - position, text-align, color, background, etc.) to define style of the button. Properties are set during creation of the Button instance and are changed occasionally (eg. position is changed on window size change by the user). Let's focus on the position. After window change, position should be reinitialized using Transform method.

  • There will be quite few properties to control style of the Button. Not all of them have to be used, so they shouldn't be passed as the constructor's parameters.
  • Transform method cannot be set inside Display method due to its repeat cycle - it's invoked every frame (target is 16.6ms), not an optimal solution.

Main problem with the current solution is that it doesn't work. If I set value of _transformed in the constructor then properties don't have values set, so it looks like _transformed = Util.Transform(0, 0, Align.Center) all the time.

Solutions

1. Simplest solution would be to add method that are invoked after initialization and on window size change:

public void Init() {
    _transformed = Util.Transform(X, Y, Align.Center);
}

but it is not a good option in my opinion, due to given examples of usage:

public GUI() {
    _button = new Button( ) { X = 64, Y = 64 }
    _button.Init();
    _button2 = new Button( ) { X = 128, Y = 256 }
    _button2.Init();
    // ...
}
// Or...
public GUI() {
    (_button = new Button( ) { X = 64, Y = 64 }).Init();
    (_button2 = new Button( ) { X = 64, Y = 64 }).Init();
    (_button3 = new Button( ) { X = 64, Y = 64 }).Init();
    // ...
}

2. I can move invoke of the Transform method to the property, but it's still invoking Transform method each frame

private Tuple<int, int> Transformed { get { return Util.Transform(X, Y, Align.Center); } }

public void Display() {
    // DrawButtonText(Transformed ...)
    // DrawBorder(Transformed ...)
    // DrawBackground(Transformed ...)
}

I think that the best solution is just to let it invoke Transform in the Display method, but I'm curious if there is a better, more optimal way to implement it as I described without continuously overwriting the field with the same value.



from Recent Questions - Stack Overflow https://ift.tt/338kKxv
https://ift.tt/eA8V8J

No comments:

Post a Comment