Changeset View
Standalone View
binaries/data/mods/public/gui/session/developer_overlay.js
function DeveloperOverlay() | |||||
{ | |||||
Stan: Shouldn't you declare that after the code ? | |||||
Done Inline ActionsMy thoughts were:
vladislavbelov: My thoughts were:
1. You need to know a name of the variable first.
2. You need to know an… | |||||
Done Inline ActionsDoes this work? I would have thought the definition of DeveloperOverlay was unknown at that time. wraitii: Does this work? I would have thought the definition of DeveloperOverlay was unknown at that… | |||||
Done Inline ActionsI guess it works because it's js and it's not parsed in a conventional way Stan: I guess it works because it's js and it's not parsed in a conventional way | |||||
Done Inline ActionsIt should: https://eslint.org/docs/rules/no-use-before-define. But I'm not sure do we need that? vladislavbelov: It should: https://eslint.org/docs/rules/no-use-before-define. But I'm not sure do we need that? | |||||
Done Inline ActionsI'd rather put it below the declaration, I think it's more consistent with what we do elsewhere and c++ code. wraitii: I'd rather put it below the declaration, I think it's more consistent with what we do elsewhere… | |||||
Done Inline ActionsI agree. It will likely cause issues if/when we used ES6 classes after sm 45 is merged. Should be in CC Stan: I agree. It will likely cause issues if/when we used ES6 classes after sm 45 is merged. Should… | |||||
this.commandHeight = 20; | |||||
this.displayState = false; | |||||
this.timeWarp = false; | |||||
Done Inline Actionsthis.commands => DeveloperOverlay.prototype.Commands would make the ctor easier to read, less fragmented elexis: `this.commands` => `DeveloperOverlay.prototype.Commands` would make the ctor easier to read… | |||||
Done Inline ActionsLike this: DeveloperOverlay.prototype.commands = [ // ... ]; ? vladislavbelov: Like this:
```lang=js
DeveloperOverlay.prototype.commands = [
// ...
];
```
? | |||||
Done Inline Actionsyes elexis: yes
not sure if Commands or commands | |||||
Done Inline ActionsBy CC we have commands. vladislavbelov: By CC we have `commands`. | |||||
this.changePerspective = false; | |||||
this.controlAll = false; | |||||
Engine.GetGUIObjectByName("devCommandsOverlay").onPress = this.toggle; | |||||
this.layout(); | |||||
Done Inline ActionsMight want to rename "callback" to "press" or "onPress" and "initValue" to "checked", so that the property names of this object match the property names of the GUI object, thus making it a bit easier for the reader. checked may be reused after init, for example if another player revealed the map (doing it once per turn sounds like accumulating performance cost, dunno) space after { before } elexis: Might want to rename "callback" to "press" or "onPress" and "initValue" to "checked", so that… | |||||
Done Inline Actions
Yeah, that was an idea for the separate layout function.
It makes sense. vladislavbelov: > checked may be reused after init, for example if another player revealed the map (doing it… | |||||
} | |||||
DeveloperOverlay.prototype.getCommands = function() { | |||||
return [ | |||||
Done Inline ActionsThis function is only used here and only has two arguments, so inlining here would fit. elexis: This function is only used here and only has two arguments, so inlining here would fit.
(also… | |||||
{ | |||||
"label": translate("Control all units"), | |||||
Not Done Inline ActionsDeveloperOverlay.prototype.getCommands = function() { return [ Why not DeveloperOverlay.prototype.Commands = [ Not only shorter, but if one uses function + return, then someone will sooner or later add some variables before the return that will be global to the entire Commands array. But the idea was to only have local variables, so that one doesn't have to read the global scope to understand an individual array item. elexis: ```
DeveloperOverlay.prototype.getCommands = function() {
return [
```
Why not
```… | |||||
Done Inline ActionsI got an error, this isn't the DeveloperOverlay. We create an array and only then assign it to the prototype. I didn't go deeper, but it seems logically. vladislavbelov: I got an error, `this` isn't the `DeveloperOverlay`. We create an array and only then assign it… | |||||
Not Done Inline ActionsYes, this in JS is the callee, one can do it like Stan said (IIRC on IRC), with a self => ... function and passing this. elexis: Yes, `this` in JS is the callee, one can do it like Stan said (IIRC on IRC), with a `self => ... | |||||
Done Inline ActionsYes, self is used for capturing the current scope this. Do you mean this: DeveloperOverlay.prototype.commands = [ // ... { "checked": self => self.controlAll }, ]; ? If yes, it looks more like a workaround. Because the problem is that we try to use the external function like it's an object method. Probably we could use "checked": overlay => overlay.controlAll, but it still looks strange for me. vladislavbelov: Yes, `self` is used for capturing the current scope `this`.
Do you mean this:
```lang=js… | |||||
Not Done Inline ActionsAnother option: Another option: DeveloperOverlay.prototype.getCommands = () => [ This way it's less likely that someone adds a not-so-local variable, but still not as preventive. (I hadn't found a satisfying solution for this, I didn't check the class keyword.) elexis: Another option:
Using JS call() function, so that one can set the `this` reference manually. | |||||
Done Inline ActionsDeveloperOverlay.prototype.getCommands = () =>...; doesn't work too, it captures wrong scope. vladislavbelov: `DeveloperOverlay.prototype.getCommands = () =>...;` doesn't work too, it captures wrong scope. | |||||
Not Done Inline ActionsIsn't the issue here that this shouldn't be a prototype/class property but rather a property of the object itself, with the prototype having a default [] implementation? Then we could skip the function and use this directly perhaps? wraitii: Isn't the issue here that this shouldn't be a prototype/class property but rather a property of… | |||||
Done Inline ActionsNo, @elexis's idea is to have commands as prototype. vladislavbelov: No, @elexis's idea is to have commands as prototype. | |||||
Not Done Inline ActionsYes, my question was more "should it be part of the prototype" over just being part of the instance. If you look at https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/Prototypes_Objet for instance, they refer to this very problem and say that probably we should just instantiate this in the constructor. I find myself agreeing, just move the Commands array to the constructor and the problem is solved. GetCommands is then just an accessor to that. wraitii: Yes, my question was more "should it be part of the prototype" over just being part of the… | |||||
Done Inline ActionsActually that was the first version (initializing in ctor), but @elexis`s suggested to separate it to have a shorter ctor. vladislavbelov: Actually that was the first version (initializing in ctor), but @elexis`s suggested to separate… | |||||
Not Done Inline Actionsshorted ctor but we have to use self to access this doesn't seem like much of an improvement to me. Though I would put this.commands last to improve readability as I agree with the "fragmented" part of the comment. wraitii: shorted ctor but we have to use `self` to access `this` doesn't seem like much of an… | |||||
Not Done Inline Actions
Much is arbitrary. elexis: > doesn't seem like much of an improvement to me
Much is arbitrary.
There specific pros and… | |||||
"onPress": checked => { | |||||
Engine.PostNetworkCommand({ | |||||
"type": "control-all", | |||||
Not Done Inline Actionsthis, or self elexis: `this`, or `self` | |||||
Done Inline ActionsWhy? It's not DeveloperOverlay. vladislavbelov: Why? It's not `DeveloperOverlay`. | |||||
Not Done Inline Actionsoh, can't read, g_DevSettings` -> this.settings or something elexis: oh, can't read,
but still the global should be avoided now, because its logically related to… | |||||
Done Inline ActionsI'd suggest to remove it in a separate patch. Because there're at least 4 files that touch the g_DevSettings. vladislavbelov: I'd suggest to remove it in a separate patch. Because there're at least 4 files that touch the… | |||||
"flag": checked | |||||
}); | |||||
}, | |||||
"checked": () => false || this.controlAll, | |||||
elexisUnsubmitted Done Inline Actionsplacebo false elexis: placebo false | |||||
}, | |||||
Done Inline Actions(false || x is still x) elexis: (false || x is still x) | |||||
Done Inline ActionsIndeed. vladislavbelov: Indeed. | |||||
Not Done Inline ActionsIf you had enough of this and want to commit it your choice, but if you didn't have enough of it, this one actually looks like if it would be better off with not using this.controlAll but using the simulation state to see if this is checked. There is controlsAll in GetSimulationState, so I would recommend to use that instead and nuke the local variable. Reproduce:
(I think the case was mentioned above too) elexis: If you had enough of this and want to commit it your choice, but if you didn't have enough of… | |||||
Done Inline ActionsBut the this.controlAll is set each turn from the simulation state. this.controlAll is used as a cache, instead of calling the GetSimState everytime. vladislavbelov: But the `this.controlAll` is set each turn from the simulation state. `this.controlAll` is used… | |||||
Not Done Inline ActionsUseless, GetSimState is cached already elexis: Useless, GetSimState is cached already | |||||
Not Done Inline Actions(As mentioned when you commit is your choice, I don't request a change, the unneeded variable is only something I observe and describe) elexis: (As mentioned when you commit is your choice, I don't request a change, the unneeded variable… | |||||
{ | |||||
"label": translate("Change perspective"), | |||||
"onPress": checked => { | |||||
this.setChangePerspective(checked); | |||||
selectViewPlayer(g_ViewedPlayer); | |||||
elexisUnsubmitted Done Inline ActionsConsider moving the selectViewPlayer call into setChangePerspective, so that if something else calls setChangePerspective, then the view will be updated correctly elexis: Consider moving the `selectViewPlayer` call into `setChangePerspective`, so that if something… | |||||
}, | |||||
Done Inline ActionsIt indicates that the return value is read from, but this is only intended as a statement, so better wrap it in a scope elexis: It indicates that the return value is read from, but this is only intended as a statement, so… | |||||
Done Inline ActionsDo you mean that the checked => g_Selection.SetMotionDebugOverlay(checked) returns a function that returns value of g_Selection.SetMotionDebugOverlay(checked)? vladislavbelov: Do you mean that the `checked => g_Selection.SetMotionDebugOverlay(checked)` returns a function… | |||||
}, | |||||
{ | |||||
"label": translate("Display selection state"), | |||||
"onPress": checked => { this.displayState = checked; }, | |||||
elexisUnsubmitted Done Inline Actions=> {\n if you wish elexis: `=> {\n` if you wish | |||||
}, | |||||
Done Inline ActionsIsn't that function supposed to return something ? Stan: Isn't that function supposed to return something ? | |||||
Done Inline ActionsNope, it's just an event. vladislavbelov: Nope, it's just an event. | |||||
Done Inline ActionsDoes Engine.GuiInterfaceCall("SetObstructionDebugOverlay", checked) return something then ? Else you should change all the lines, not only one. Stan: Does Engine.GuiInterfaceCall("SetObstructionDebugOverlay", checked) return something then ? | |||||
{ | |||||
"label": translate("Pathfinder overlay"), | |||||
"onPress": checked => { | |||||
Engine.GuiInterfaceCall("SetPathfinderDebugOverlay", checked); | |||||
}, | |||||
}, | |||||
{ | |||||
"label": translate("Obstruction overlay"), | |||||
"onPress": checked => { | |||||
Engine.GuiInterfaceCall("SetObstructionDebugOverlay", checked); | |||||
}, | |||||
}, | |||||
{ | |||||
"label": translate("Unit motion overlay"), | |||||
"onPress": checked => { | |||||
g_Selection.SetMotionDebugOverlay(checked); | |||||
}, | |||||
}, | |||||
{ | |||||
"label": translate("Range overlay"), | |||||
Done Inline ActionsThis function is only one command and only called from here, so it should be moved here elexis: This function is only one command and only called from here, so it should be moved here | |||||
"onPress": checked => { | |||||
Engine.GuiInterfaceCall("SetRangeDebugOverlay", checked); | |||||
}, | |||||
}, | |||||
{ | |||||
"label": translate("Bounding box overlay"), | |||||
"onPress": checked => { | |||||
Engine.SetBoundingBoxDebugOverlay(checked); | |||||
}, | |||||
}, | |||||
{ | |||||
"label": translate("Restrict camera"), | |||||
"onPress": checked => { | |||||
Engine.GameView_SetConstrainCameraEnabled(checked); | |||||
}, | |||||
"checked": () => true, | |||||
}, | |||||
Done Inline Actionsarguably needless elexis: arguably needless | |||||
Done Inline ActionsInitially I thought to re-layout the overlay, but it's not needed. vladislavbelov: Initially I thought to re-layout the overlay, but it's not needed. | |||||
{ | |||||
Not Done Inline ActionsAs far as I read, checked() is rebuilt everytime updateGuiObjects is called, i.e. once or more often per turn, but then it sounds like this checkbox is always ticked? elexis: As far as I read, checked() is rebuilt everytime updateGuiObjects is called, i.e. once or more… | |||||
Done Inline ActionsYou're right, I missed Engine.GameView_GetConstrainCameraEnabled there (as I wanted to add). We see again how a review is important. Thank you! vladislavbelov: You're right, I missed `Engine.GameView_GetConstrainCameraEnabled` there (as I wanted to add). | |||||
Not Done Inline ActionsIt's not like the author couldn't have found it himself by putting every line under scrutiny. elexis: It's not like the author couldn't have found it himself by putting every line under scrutiny. | |||||
"label": translate("Reveal map"), | |||||
"onPress": checked => { | |||||
Engine.PostNetworkCommand({ | |||||
"type": "reveal-map", | |||||
"enable": checked | |||||
}); | |||||
}, | |||||
"checked": () => Engine.GuiInterfaceCall("IsMapRevealed"), | |||||
}, | |||||
{ | |||||
"label": translate("Enable time warp"), | |||||
"onPress": checked => { | |||||
Not Done Inline ActionsHaving this prototype in the object directly would be nice for editability, but typically messes with the this reference. Luckily there is none here. elexis: Having this prototype in the object directly would be nice for editability, but typically… | |||||
Not Done Inline ActionsUsually that's when you declare a let self = this and use it in the function no ? Stan: Usually that's when you declare a let self = this and use it in the function no ? | |||||
Not Done Inline Actionsthis is referenced depending on the caller elexis: `this` is referenced depending on the caller | |||||
Done Inline Actionsunnecessary scope ); after translate("Time warp mode") if you agree elexis: unnecessary scope
`);` after `translate("Time warp mode")` if you agree | |||||
Done Inline ActionsDo you mean: messageBox( 500, 250, translate("Note: time warp mode is a developer option, and not intended for use over long periods of time. Using it incorrectly may cause the game to run out of memory or crash."), translate("Time warp mode")); ? vladislavbelov: Do you mean:
```lang=js
messageBox(
500, 250,
translate("Note: time warp mode is a developer… | |||||
Done Inline Actionsyes elexis: yes | |||||
this.timeWarp = checked; | |||||
if (checked) | |||||
{ | |||||
messageBox( | |||||
500, 250, | |||||
translate("Note: time warp mode is a developer option, and not intended for use over long periods of time. Using it incorrectly may cause the game to run out of memory or crash."), | |||||
translate("Time warp mode")); | |||||
} | |||||
elexisUnsubmitted Done Inline Actionsunneeded scope elexis: unneeded scope
`- {}` | |||||
Engine.EnableTimeWarpRecording(checked ? 10 : 0); | |||||
}, | |||||
}, | |||||
{ | |||||
"label": translate("Promote selected units"), | |||||
"onPress": checked => { | |||||
Engine.PostNetworkCommand({ | |||||
"type": "promote", | |||||
"entities": g_Selection.toList() | |||||
}); | |||||
}, | |||||
}, | |||||
{ | |||||
"label": translate("Hierarchical pathfinder overlay"), | |||||
"onPress": checked => { | |||||
Engine.GuiInterfaceCall("SetPathfinderHierDebugOverlay", checked); | |||||
}, | |||||
Not Done Inline Actionsthe 3 lines above and 4 lines here should be one pack of 7 lines, not split by 100 unrelated lines elexis: the 3 lines above and 4 lines here should be one pack of 7 lines, not split by 100 unrelated… | |||||
}, | |||||
]; | |||||
}; | |||||
DeveloperOverlay.prototype.layout = function() | |||||
{ | |||||
for (let body of Engine.GetGUIObjectByName("dev_commands").children) | |||||
body.hidden = true; | |||||
let overlayHeight = 0; | |||||
let commands = this.getCommands(); | |||||
for (let i = 0; i < commands.length; ++i) | |||||
{ | |||||
let command = commands[i]; | |||||
let body = Engine.GetGUIObjectByName("dev_command[" + i + "]"); | |||||
let bodySize = body.size; | |||||
bodySize.top = i * this.commandHeight; | |||||
bodySize.bottom = bodySize.top + this.commandHeight; | |||||
body.size = bodySize; | |||||
body.hidden = false; | |||||
Done Inline ActionsIt's not so obvious how many files we want to create, as there are thousands of lines of code in session/. elexis: It's not so obvious how many files we want to create, as there are thousands of lines of code… | |||||
Done Inline ActionsDo we have some basic structure of such object? JS doesn't have a classic OOP. So it's harder to avoid some global/public stuff. Should the object be like this? function DeveloperOverlay() {} // Or any other way to define an object. DeveloperOverlay.prototype.layout = function() { // ... } let overlay = new DeveloperOverlay(); P.S. Some time ago wraitii sent a link to a video about OOP, it's called like "OOP is dead, Data Driven/Oriented Design is a key" :P vladislavbelov: Do we have some basic structure of such object? JS doesn't have a classic OOP. So it's harder… | |||||
Done Inline ActionsThat's what I had in mind, DeveloperOverlayManager and g_DeveloperOverlayManager maybe. elexis: That's what I had in mind, DeveloperOverlayManager and g_DeveloperOverlayManager maybe.
I guess… | |||||
Done Inline ActionsUsually *Manager means that it manages something (not itself), for ex. multiple objects. vladislavbelov: Usually `*Manager` means that it manages something (not itself), for ex. multiple objects. | |||||
Not Done Inline ActionsWith ES6 Classes I think this kind of global objects would look neater, I agree with elexis that's it's a good idea. wraitii: With ES6 Classes I think this kind of global objects would look neater, I agree with elexis… | |||||
let label = Engine.GetGUIObjectByName("dev_command_label[" + i + "]"); | |||||
label.caption = command.label; | |||||
let checkbox = Engine.GetGUIObjectByName("dev_command_checkbox[" + i + "]"); | |||||
checkbox.onPress = function() { | |||||
command.onPress(checkbox.checked); | |||||
if (command.checked) | |||||
checkbox.checked = command.checked(); | |||||
}; | |||||
overlayHeight += this.commandHeight; | |||||
} | |||||
Not Done Inline ActionsINVALID_PLAYER if that exists. Stan: INVALID_PLAYER if that exists. | |||||
Done Inline ActionsIt's not present. vladislavbelov: It's not present. | |||||
let overlay = Engine.GetGUIObjectByName("devCommandsOverlay"); | |||||
elexisUnsubmitted Not Done Inline Actionslet devCommandsOverlay = Engine.GetGUIObjectByName("devCommandsOverlay"); (if you agree and like and want to invest the time) elexis: `let devCommandsOverlay = Engine.GetGUIObjectByName("devCommandsOverlay");` (if you agree and… | |||||
vladislavbelovAuthorUnsubmitted Done Inline ActionsI'd prefer to use a shorter name, because a reader knows the context (DeveloperOverlay), but for other overlays here (if they'll present) we need to use a full name. The same below. vladislavbelov: I'd prefer to use a shorter name, because a reader knows the context (`DeveloperOverlay`), but… | |||||
let overlaySize = overlay.size; | |||||
overlaySize.bottom = overlaySize.top + overlayHeight; | |||||
overlay.size = overlaySize; | |||||
this.updateValues(); | |||||
}; | |||||
DeveloperOverlay.prototype.updateValues = function() | |||||
{ | |||||
let commands = this.getCommands(); | |||||
for (let i = 0; i < commands.length; ++i) | |||||
{ | |||||
let command = commands[i]; | |||||
let body = Engine.GetGUIObjectByName("dev_command[" + i + "]"); | |||||
if (body.hidden) | |||||
continue; | |||||
let checkbox = Engine.GetGUIObjectByName("dev_command_checkbox[" + i + "]"); | |||||
elexisUnsubmitted Not Done Inline Actionslet dev_command_checkbox = Engine.GetGUIObjectByName("dev_command_checkbox[" + i + "]"); (same) elexis: `let dev_command_checkbox = Engine.GetGUIObjectByName("dev_command_checkbox[" + i + "]");`… | |||||
if (command.checked) | |||||
checkbox.checked = command.checked(); | |||||
} | |||||
}; | |||||
DeveloperOverlay.prototype.toggle = function() | |||||
{ | |||||
if (!g_GameAttributes.settings.CheatsEnabled && !g_IsReplay) | |||||
return; | |||||
let devCommands = Engine.GetGUIObjectByName("devCommandsOverlay"); | |||||
elexisUnsubmitted Not Done Inline Actionslet devCommandsOverlay = Engine.GetGUIObjectByName("devCommandsOverlay"); (same) elexis: `let devCommandsOverlay = Engine.GetGUIObjectByName("devCommandsOverlay");` (same) | |||||
devCommands.hidden = !devCommands.hidden; | |||||
let message = devCommands.hidden ? | |||||
markForTranslation("The Developer Overlay was closed.") : | |||||
markForTranslation("The Developer Overlay was opened."); | |||||
// Only players can send the simulation chat command | |||||
if (Engine.GetPlayerID() == -1) | |||||
submitChatDirectly(message); | |||||
else | |||||
Engine.PostNetworkCommand({ | |||||
"type": "aichat", | |||||
"message": message, | |||||
"translateMessage": true, | |||||
"translateParameters": [], | |||||
"parameters": {} | |||||
}); | |||||
}; | |||||
DeveloperOverlay.prototype.update = function() | |||||
{ | |||||
this.updateValues(); | |||||
let debug = Engine.GetGUIObjectByName("debugEntityState"); | |||||
if (!this.displayState) | |||||
{ | |||||
debug.hidden = true; | |||||
return; | |||||
} | |||||
debug.hidden = false; | |||||
let conciseSimState = clone(GetSimState()); | |||||
conciseSimState.players = "<<<omitted>>>"; | |||||
let text = "simulation: " + uneval(conciseSimState); | |||||
let selection = g_Selection.toList(); | |||||
if (selection.length) | |||||
{ | |||||
let entState = GetEntityState(selection[0]); | |||||
if (entState) | |||||
{ | |||||
let template = GetTemplateData(entState.template); | |||||
text += "\n\nentity: {\n"; | |||||
for (let k in entState) | |||||
text += " " + k + ":" + uneval(entState[k]) + "\n"; | |||||
text += "}\n\ntemplate: " + uneval(template); | |||||
} | |||||
} | |||||
debug.caption = text.replace(/\[/g, "\\["); | |||||
Not Done Inline ActionsHiding such globals at the bottom is also an anti-pattern problem we find in C++. I wonder if it wouldn't be better to define it at the top of session.js (undefined init, and then init in the init function). That the init is done on file-load also sounds more problematic than init on the init function. At last, about init, there is the hotloading thing. elexis: Hiding such globals at the bottom is also an anti-pattern problem we find in C++.
I wonder if… | |||||
Not Done Inline ActionsI think we could get away with not using the variable if we tied this code with its GUI element more on the c++ side, so that we would have a more react-like behaviour. But that requires more thinking to get it right the first time, and I'm not sure it's worth stopping this revision over. wraitii: I think we could get away with not using the variable if we tied this code with its GUI element… | |||||
}; | |||||
DeveloperOverlay.prototype.isTimeWarpEnabled = function() { | |||||
return this.timeWarp; | |||||
}; | |||||
DeveloperOverlay.prototype.isChangePerspective = function() { | |||||
return this.changePerspective; | |||||
}; | |||||
DeveloperOverlay.prototype.setChangePerspective = function(value) { | |||||
this.changePerspective = value; | |||||
}; | |||||
Not Done Inline Actionsthis setter is never called, not sure if it is good to have it, and if it was there, it should update the GUI checkbox and state I suppose. (The onPress function could call setChangePerspective if you want to keep it without having it be dead code, and reduces the amount of code by one line) elexis: this setter is never called, not sure if it is good to have it, and if it was there, it should… | |||||
Done Inline ActionsonPress looks ok for me. vladislavbelov: `onPress` looks ok for me. | |||||
Not Done Inline ActionsDeveloperOverlay.prototype.setChangePerspective = function(value) { this.changePerspective = value; selectViewPlayer(g_ViewedPlayer); }; "onPress": checked => { this.setChangePerspective(checked); }, (or "onPress": this.setChangePerspective) this way the function would not be dead, and it would to the update if it was used from some other place. Can nuke the dead function too. or keep it. elexis: ```
DeveloperOverlay.prototype.setChangePerspective = function(value) {
this.changePerspective… | |||||
Done Inline ActionsYeah, I meant I agree with the onPress modification. vladislavbelov: Yeah, I meant I agree with the `onPress` modification. | |||||
DeveloperOverlay.prototype.isControlAll = function() { | |||||
return this.controlAll; | |||||
}; | |||||
DeveloperOverlay.prototype.setControlAll = function(value) { | |||||
this.controlAll = value; | |||||
}; | |||||
Done Inline ActionsNewline. Stan: Newline. | |||||
Done Inline ActionsAlready fixed. vladislavbelov: Already fixed. |
Shouldn't you declare that after the code ?