stormwarestudios Posted February 25, 2018 Share Posted February 25, 2018 Hello, I'm (slowly!) building the GUI for my game, and I believe I have a use-case which the current API does not cover. I have a workaround, but I thought I would discuss it here. The game itself is a client/server model (websockets for transport), where various states of the GUI are loaded from the server once the user has jumped through the usual hoops (auth, chosen context, etc). For example, the current feature I am developing involves Slider controls. What I want to do with the sliders is three things: Once the hoop-jumping is done, Slider state is loaded from the server, and the Slider value is set. A player may be an initiator of a Slider value-change, whereby I use the onValueChangedObservable event to send the change to the server. Such changes are broadcast to all players sharing a similar context. A different player who shares context as #2 may be a receiver of a Slider value-change (e.g. as done by a player in #2), whereby I must update the Slider value without triggering onValueChangedObservable and just cause the slider appearance to be modified. In the case of #1, when I load the Slider value from the server and set Slider.value = newValue, this triggers a onValueChangedObservable, which pushes the change to the server, which would broadcast the value change to all clients in the same context, which would cause their Sliders to update, which would trigger onValueChangedObservable, and so on, until a rift in the spacetime continuum appears. In the case of #2, the same sort of thing may occur, except initiated by a player. What I have done to avoid the onValueChangedObservable trigger, is to call: Slider._value = newValue; Slider._markAsDirty(); This works perfectly, and does not trigger onValueChangedObservable. However, it feels ... dirty. Is there a better way to handle this? I suspect I'll get deep into this pattern once I get to the rest of the types of controls I have planned. Quote Link to comment Share on other sites More sharing options...
RaananW Posted February 26, 2018 Share Posted February 26, 2018 Oh, I like those software-architecture questions I see a few different ways of handling this (the one you suggested is actually one of them) 1) Override the value-setter of the slider. Something along this line: Object.defineProperty(BABYLON.GUI.Slider.prototype, "value", { get: function () { return this._value; }, set: function (value) { value = Math.max(Math.min(value, this._maximum), this._minimum); if (this._value === value) { return; } this._value = value; this._markAsDirty(); // this.onValueChangedObservable.notifyObservers(this._value); }, enumerable: true, configurable: true }); So the setter now don't notify the observers. You will need to do it manually, when the user changes the value (detecting that should be easy) 2) Push a function to the onValueChanged observable that will stop observable iteration if a server value was received. You will need to set skipNextObservers to true in the event state object, which will prevent the next observers to be executed). If it is user-triggered, don't set it to true, and the value will be sent to the server. Wingnut 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.