Page MenuHomeWildfire Games

Cache g_UnitActions sorted instead of computing it every tick.
ClosedPublic

Authored by Freagarach on Feb 16 2020, 1:16 PM.

Details

Reviewers
Silier
Group Reviewers
Restricted Owners Package(Owns No Changed Paths)
Commits
rP23602: Cache keys of g_UnitActions sorted instead of computing it every tick.
Summary

This caches g_UnitActions sorted, which was computed in input.js on every tick. Since g_UnitActions does not change in the progress of a game it can be cached upon init.
Relevant timing differences:

  • Init: From non-existent to ~130 microseconds.
  • OnTick (and mouse movement): From ~100 to ~5 microseconds.

Why this is bad:

  • It introduces another global variable. (I would say we can just sort g_UnitActions itself, for we have no need of the unsorted variant?) < Not possible.

Why this is good:

  • It speeds up determineAction in input.js significantly.
Test Plan

Verify that neither errors nor warnings are thrown when selecting entities and moving the mouse-pointer around, thus that everything functions as it should.

Event Timeline

Freagarach created this revision.Feb 16 2020, 1:16 PM
Owners added a subscriber: Restricted Owners Package.Feb 16 2020, 1:16 PM

Successful build - Chance fights ever on the side of the prudent.

Linter detected issues:
Executing section Source...
Executing section JS...

binaries/data/mods/public/gui/session/unit_actions.js
| 568| »   »   »   switch·(tradingDetails.type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.
|    | [NORMAL] ESLintBear (space-unary-ops):
|    | Unary word operator 'typeof' must be followed by whitespace.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 335| 335| 	}
| 336| 336| 
| 337| 337| 	var wallPlacementInfo = updateBuildingPlacementPreview(); // entities making up the wall (wall segments, towers, ...)
| 338|    |-	if (!(wallPlacementInfo === false || typeof(wallPlacementInfo) === "object"))
|    | 338|+	if (!(wallPlacementInfo === false || typeof (wallPlacementInfo) === "object"))
| 339| 339| 	{
| 340| 340| 		error("Invalid updateBuildingPlacementPreview return value: " + uneval(wallPlacementInfo));
| 341| 341| 		return false;
|    | [NORMAL] ESLintBear (operator-linebreak):
|    | '&&' should be placed at the end of the line.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 485| 485| 	mouseIsOverObject = (hoveredObject != null);
| 486| 486| 
| 487| 487| 	// Close the menu when interacting with the game world
| 488|    |-	if (!mouseIsOverObject && (ev.type =="mousebuttonup" || ev.type == "mousebuttondown")
| 489|    |-		&& (ev.button == SDL_BUTTON_LEFT || ev.button == SDL_BUTTON_RIGHT))
|    | 488|+	if (!mouseIsOverObject && (ev.type =="mousebuttonup" || ev.type == "mousebuttondown") &&
|    | 489|+		(ev.button == SDL_BUTTON_LEFT || ev.button == SDL_BUTTON_RIGHT))
| 490| 490| 		g_Menu.close();
| 491| 491| 
| 492| 492| 	// State-machine processing:
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 646| 646| 		// user to continue building walls.
| 647| 647| 		switch (ev.type)
| 648| 648| 		{
| 649|    |-			case "mousemotion":
|    | 649|+		case "mousemotion":
| 650| 650| 				placementSupport.wallEndPosition = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
| 651| 651| 
| 652| 652| 				// Update the structure placement preview, and by extension, the list of snapping candidate entities for both (!)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 647| 647| 		switch (ev.type)
| 648| 648| 		{
| 649| 649| 			case "mousemotion":
| 650|    |-				placementSupport.wallEndPosition = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
|    | 650|+			placementSupport.wallEndPosition = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
| 651| 651| 
| 652| 652| 				// Update the structure placement preview, and by extension, the list of snapping candidate entities for both (!)
| 653| 653| 				// the ending point and the starting point to snap to.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 649| 649| 			case "mousemotion":
| 650| 650| 				placementSupport.wallEndPosition = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
| 651| 651| 
| 652|    |-				// Update the structure placement preview, and by extension, the list of snapping candidate entities for both (!)
|    | 652|+			// Update the structure placement preview, and by extension, the list of snapping candidate entities for both (!)
| 653| 653| 				// the ending point and the starting point to snap to.
| 654| 654| 				//
| 655| 655| 				// TODO: Note that here, we need to fetch all similar entities, including any offscreen ones, to support the case
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 650| 650| 				placementSupport.wallEndPosition = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
| 651| 651| 
| 652| 652| 				// Update the structure placement preview, and by extension, the list of snapping candidate entities for both (!)
| 653|    |-				// the ending point and the starting point to snap to.
|    | 653|+			// the ending point and the starting point to snap to.
| 654| 654| 				//
| 655| 655| 				// TODO: Note that here, we need to fetch all similar entities, including any offscreen ones, to support the case
| 656| 656| 				// where the snap entity for the starting point has moved offscreen, or has been deleted/destroyed, or was a
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 651| 651| 
| 652| 652| 				// Update the structure placement preview, and by extension, the list of snapping candidate entities for both (!)
| 653| 653| 				// the ending point and the starting point to snap to.
| 654|    |-				//
|    | 654|+			//
| 655| 655| 				// TODO: Note that here, we need to fetch all similar entities, including any offscreen ones, to support the case
| 656| 656| 				// where the snap entity for the starting point has moved offscreen, or has been deleted/destroyed, or was a
| 657| 657| 				// foundation and has been replaced with a completed entity since the user first chose it. Fetching all towers on
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 652| 652| 				// Update the structure placement preview, and by extension, the list of snapping candidate entities for both (!)
| 653| 653| 				// the ending point and the starting point to snap to.
| 654| 654| 				//
| 655|    |-				// TODO: Note that here, we need to fetch all similar entities, including any offscreen ones, to support the case
|    | 655|+			// TODO: Note that here, we need to fetch all similar entities, including any offscreen ones, to support the case
| 656| 656| 				// where the snap entity for the starting point has moved offscreen, or has been deleted/destroyed, or was a
| 657| 657| 				// foundation and has been replaced with a completed entity since the user first chose it. Fetching all towers on
| 658| 658| 				// the entire map instead of only the current screen might get expensive fast since walls all have a ton of towers
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 653| 653| 				// the ending point and the starting point to snap to.
| 654| 654| 				//
| 655| 655| 				// TODO: Note that here, we need to fetch all similar entities, including any offscreen ones, to support the case
| 656|    |-				// where the snap entity for the starting point has moved offscreen, or has been deleted/destroyed, or was a
|    | 656|+			// where the snap entity for the starting point has moved offscreen, or has been deleted/destroyed, or was a
| 657| 657| 				// foundation and has been replaced with a completed entity since the user first chose it. Fetching all towers on
| 658| 658| 				// the entire map instead of only the current screen might get expensive fast since walls all have a ton of towers
| 659| 659| 				// in them. Might be useful to query only for entities within a certain range around the starting point and ending
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 654| 654| 				//
| 655| 655| 				// TODO: Note that here, we need to fetch all similar entities, including any offscreen ones, to support the case
| 656| 656| 				// where the snap entity for the starting point has moved offscreen, or has been deleted/destroyed, or was a
| 657|    |-				// foundation and has been replaced with a completed entity since the user first chose it. Fetching all towers on
|    | 657|+			// foundation and has been replaced with a completed entity since the user first chose it. Fetching all towers on
| 658| 658| 				// the entire map instead of only the current screen might get expensive fast since walls all have a ton of towers
| 659| 659| 				// in them. Might be useful to query only for entities within a certain range around the starting point and ending
| 660| 660| 				// points.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 655| 655| 				// TODO: Note that here, we need to fetch all similar entities, including any offscreen ones, to support the case
| 656| 656| 				// where the snap entity for the starting point has moved offscreen, or has been deleted/destroyed, or was a
| 657| 657| 				// foundation and has been replaced with a completed entity since the user first chose it. Fetching all towers on
| 658|    |-				// the entire map instead of only the current screen might get expensive fast since walls all have a ton of towers
|    | 658|+			// the entire map instead of only the current screen might get expensive fast since walls all have a ton of towers
| 659| 659| 				// in them. Might be useful to query only for entities within a certain range around the starting point and ending
| 660| 660| 				// points.
| 661| 661| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 656| 656| 				// where the snap entity for the starting point has moved offscreen, or has been deleted/destroyed, or was a
| 657| 657| 				// foundation and has been replaced with a completed entity since the user first chose it. Fetching all towers on
| 658| 658| 				// the entire map instead of only the current screen might get expensive fast since walls all have a ton of towers
| 659|    |-				// in them. Might be useful to query only for entities within a certain range around the starting point and ending
|    | 659|+			// in them. Might be useful to query only for entities within a certain range around the starting point and ending
| 660| 660| 				// points.
| 661| 661| 
| 662| 662| 				placementSupport.wallSnapEntitiesIncludeOffscreen = true;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 657| 657| 				// foundation and has been replaced with a completed entity since the user first chose it. Fetching all towers on
| 658| 658| 				// the entire map instead of only the current screen might get expensive fast since walls all have a ton of towers
| 659| 659| 				// in them. Might be useful to query only for entities within a certain range around the starting point and ending
| 660|    |-				// points.
|    | 660|+			// points.
| 661| 661| 
| 662| 662| 				placementSupport.wallSnapEntitiesIncludeOffscreen = true;
| 663| 663| 				var result = updateBuildingPlacementPreview(); // includes an update of the snap entity candidates
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 659| 659| 				// in them. Might be useful to query only for entities within a certain range around the starting point and ending
| 660| 660| 				// points.
| 661| 661| 
| 662|    |-				placementSupport.wallSnapEntitiesIncludeOffscreen = true;
|    | 662|+			placementSupport.wallSnapEntitiesIncludeOffscreen = true;
| 663| 663| 				var result = updateBuildingPlacementPreview(); // includes an update of the snap entity candidates
| 664| 664| 
| 665| 665| 				if (result && result.cost)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 660| 660| 				// points.
| 661| 661| 
| 662| 662| 				placementSupport.wallSnapEntitiesIncludeOffscreen = true;
| 663|    |-				var result = updateBuildingPlacementPreview(); // includes an update of the snap entity candidates
|    | 663|+			var result = updateBuildingPlacementPreview(); // includes an update of the snap entity candidates
| 664| 664| 
| 665| 665| 				if (result && result.cost)
| 666| 666| 				{
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 662| 662| 				placementSupport.wallSnapEntitiesIncludeOffscreen = true;
| 663| 663| 				var result = updateBuildingPlacementPreview(); // includes an update of the snap entity candidates
| 664| 664| 
| 665|    |-				if (result && result.cost)
|    | 665|+			if (result && result.cost)
| 666| 666| 				{
| 667| 667| 					var neededResources = Engine.GuiInterfaceCall("GetNeededResources", { "cost": result.cost });
| 668| 668| 					placementSupport.tooltipMessage = [
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 663| 663| 				var result = updateBuildingPlacementPreview(); // includes an update of the snap entity candidates
| 664| 664| 
| 665| 665| 				if (result && result.cost)
| 666|    |-				{
|    | 666|+			{
| 667| 667| 					var neededResources = Engine.GuiInterfaceCall("GetNeededResources", { "cost": result.cost });
| 668| 668| 					placementSupport.tooltipMessage = [
| 669| 669| 						getEntityCostTooltip(result),
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 664| 664| 
| 665| 665| 				if (result && result.cost)
| 666| 666| 				{
| 667|    |-					var neededResources = Engine.GuiInterfaceCall("GetNeededResources", { "cost": result.cost });
|    | 667|+				var neededResources = Engine.GuiInterfaceCall("GetNeededResources", { "cost": result.cost });
| 668| 668| 					placementSupport.tooltipMessage = [
| 669| 669| 						getEntityCostTooltip(result),
| 670| 670| 						getNeededResourcesTooltip(neededResources)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 665| 665| 				if (result && result.cost)
| 666| 666| 				{
| 667| 667| 					var neededResources = Engine.GuiInterfaceCall("GetNeededResources", { "cost": result.cost });
| 668|    |-					placementSupport.tooltipMessage = [
|    | 668|+				placementSupport.tooltipMessage = [
| 669| 669| 						getEntityCostTooltip(result),
| 670| 670| 						getNeededResourcesTooltip(neededResources)
| 671| 671| 					].filter(tip => tip).join("\n");
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 666| 666| 				{
| 667| 667| 					var neededResources = Engine.GuiInterfaceCall("GetNeededResources", { "cost": result.cost });
| 668| 668| 					placementSupport.tooltipMessage = [
| 669|    |-						getEntityCostTooltip(result),
|    | 669|+					getEntityCostTooltip(result),
| 670| 670| 						getNeededResourcesTooltip(neededResources)
| 671| 671| 					].filter(tip => tip).join("\n");
| 672| 672| 				}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 667| 667| 					var neededResources = Engine.GuiInterfaceCall("GetNeededResources", { "cost": result.cost });
| 668| 668| 					placementSupport.tooltipMessage = [
| 669| 669| 						getEntityCostTooltip(result),
| 670|    |-						getNeededResourcesTooltip(neededResources)
|    | 670|+					getNeededResourcesTooltip(neededResources)
| 671| 671| 					].filter(tip => tip).join("\n");
| 672| 672| 				}
| 673| 673| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 668| 668| 					placementSupport.tooltipMessage = [
| 669| 669| 						getEntityCostTooltip(result),
| 670| 670| 						getNeededResourcesTooltip(neededResources)
| 671|    |-					].filter(tip => tip).join("\n");
|    | 671|+				].filter(tip => tip).join("\n");
| 672| 672| 				}
| 673| 673| 
| 674| 674| 				break;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 669| 669| 						getEntityCostTooltip(result),
| 670| 670| 						getNeededResourcesTooltip(neededResources)
| 671| 671| 					].filter(tip => tip).join("\n");
| 672|    |-				}
|    | 672|+			}
| 673| 673| 
| 674| 674| 				break;
| 675| 675| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 671| 671| 					].filter(tip => tip).join("\n");
| 672| 672| 				}
| 673| 673| 
| 674|    |-				break;
|    | 674|+			break;
| 675| 675| 
| 676| 676| 			case "mousebuttondown":
| 677| 677| 				if (ev.button == SDL_BUTTON_LEFT)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 673| 673| 
| 674| 674| 				break;
| 675| 675| 
| 676|    |-			case "mousebuttondown":
|    | 676|+		case "mousebuttondown":
| 677| 677| 				if (ev.button == SDL_BUTTON_LEFT)
| 678| 678| 				{
| 679| 679| 					var queued = Engine.HotkeyIsPressed("session.queue");
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 674| 674| 				break;
| 675| 675| 
| 676| 676| 			case "mousebuttondown":
| 677|    |-				if (ev.button == SDL_BUTTON_LEFT)
|    | 677|+			if (ev.button == SDL_BUTTON_LEFT)
| 678| 678| 				{
| 679| 679| 					var queued = Engine.HotkeyIsPressed("session.queue");
| 680| 680| 					if (tryPlaceWall(queued))
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 675| 675| 
| 676| 676| 			case "mousebuttondown":
| 677| 677| 				if (ev.button == SDL_BUTTON_LEFT)
| 678|    |-				{
|    | 678|+			{
| 679| 679| 					var queued = Engine.HotkeyIsPressed("session.queue");
| 680| 680| 					if (tryPlaceWall(queued))
| 681| 681| 					{
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 676| 676| 			case "mousebuttondown":
| 677| 677| 				if (ev.button == SDL_BUTTON_LEFT)
| 678| 678| 				{
| 679|    |-					var queued = Engine.HotkeyIsPressed("session.queue");
|    | 679|+				var queued = Engine.HotkeyIsPressed("session.queue");
| 680| 680| 					if (tryPlaceWall(queued))
| 681| 681| 					{
| 682| 682| 						if (queued)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 677| 677| 				if (ev.button == SDL_BUTTON_LEFT)
| 678| 678| 				{
| 679| 679| 					var queued = Engine.HotkeyIsPressed("session.queue");
| 680|    |-					if (tryPlaceWall(queued))
|    | 680|+				if (tryPlaceWall(queued))
| 681| 681| 					{
| 682| 682| 						if (queued)
| 683| 683| 						{
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 678| 678| 				{
| 679| 679| 					var queued = Engine.HotkeyIsPressed("session.queue");
| 680| 680| 					if (tryPlaceWall(queued))
| 681|    |-					{
|    | 681|+				{
| 682| 682| 						if (queued)
| 683| 683| 						{
| 684| 684| 							// continue building, just set a new starting position where we left off
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 679| 679| 					var queued = Engine.HotkeyIsPressed("session.queue");
| 680| 680| 					if (tryPlaceWall(queued))
| 681| 681| 					{
| 682|    |-						if (queued)
|    | 682|+					if (queued)
| 683| 683| 						{
| 684| 684| 							// continue building, just set a new starting position where we left off
| 685| 685| 							placementSupport.position = placementSupport.wallEndPosition;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 680| 680| 					if (tryPlaceWall(queued))
| 681| 681| 					{
| 682| 682| 						if (queued)
| 683|    |-						{
|    | 683|+					{
| 684| 684| 							// continue building, just set a new starting position where we left off
| 685| 685| 							placementSupport.position = placementSupport.wallEndPosition;
| 686| 686| 							placementSupport.wallEndPosition = undefined;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 7.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 681| 681| 					{
| 682| 682| 						if (queued)
| 683| 683| 						{
| 684|    |-							// continue building, just set a new starting position where we left off
|    | 684|+						// continue building, just set a new starting position where we left off
| 685| 685| 							placementSupport.position = placementSupport.wallEndPosition;
| 686| 686| 							placementSupport.wallEndPosition = undefined;
| 687| 687| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 7.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 682| 682| 						if (queued)
| 683| 683| 						{
| 684| 684| 							// continue building, just set a new starting position where we left off
| 685|    |-							placementSupport.position = placementSupport.wallEndPosition;
|    | 685|+						placementSupport.position = placementSupport.wallEndPosition;
| 686| 686| 							placementSupport.wallEndPosition = undefined;
| 687| 687| 
| 688| 688| 							inputState = INPUT_BUILDING_WALL_CLICK;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 7.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 683| 683| 						{
| 684| 684| 							// continue building, just set a new starting position where we left off
| 685| 685| 							placementSupport.position = placementSupport.wallEndPosition;
| 686|    |-							placementSupport.wallEndPosition = undefined;
|    | 686|+						placementSupport.wallEndPosition = undefined;
| 687| 687| 
| 688| 688| 							inputState = INPUT_BUILDING_WALL_CLICK;
| 689| 689| 						}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 7.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 685| 685| 							placementSupport.position = placementSupport.wallEndPosition;
| 686| 686| 							placementSupport.wallEndPosition = undefined;
| 687| 687| 
| 688|    |-							inputState = INPUT_BUILDING_WALL_CLICK;
|    | 688|+						inputState = INPUT_BUILDING_WALL_CLICK;
| 689| 689| 						}
| 690| 690| 						else
| 691| 691| 						{
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 686| 686| 							placementSupport.wallEndPosition = undefined;
| 687| 687| 
| 688| 688| 							inputState = INPUT_BUILDING_WALL_CLICK;
| 689|    |-						}
|    | 689|+					}
| 690| 690| 						else
| 691| 691| 						{
| 692| 692| 							placementSupport.Reset();
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 687| 687| 
| 688| 688| 							inputState = INPUT_BUILDING_WALL_CLICK;
| 689| 689| 						}
| 690|    |-						else
|    | 690|+					else
| 691| 691| 						{
| 692| 692| 							placementSupport.Reset();
| 693| 693| 							inputState = INPUT_NORMAL;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 688| 688| 							inputState = INPUT_BUILDING_WALL_CLICK;
| 689| 689| 						}
| 690| 690| 						else
| 691|    |-						{
|    | 691|+					{
| 692| 692| 							placementSupport.Reset();
| 693| 693| 							inputState = INPUT_NORMAL;
| 694| 694| 						}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 7.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 689| 689| 						}
| 690| 690| 						else
| 691| 691| 						{
| 692|    |-							placementSupport.Reset();
|    | 692|+						placementSupport.Reset();
| 693| 693| 							inputState = INPUT_NORMAL;
| 694| 694| 						}
| 695| 695| 					}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 7.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 690| 690| 						else
| 691| 691| 						{
| 692| 692| 							placementSupport.Reset();
| 693|    |-							inputState = INPUT_NORMAL;
|    | 693|+						inputState = INPUT_NORMAL;
| 694| 694| 						}
| 695| 695| 					}
| 696| 696| 					else
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 691| 691| 						{
| 692| 692| 							placementSupport.Reset();
| 693| 693| 							inputState = INPUT_NORMAL;
| 694|    |-						}
|    | 694|+					}
| 695| 695| 					}
| 696| 696| 					else
| 697| 697| 						placementSupport.tooltipMessage = translate("Cannot build wall here!");
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 692| 692| 							placementSupport.Reset();
| 693| 693| 							inputState = INPUT_NORMAL;
| 694| 694| 						}
| 695|    |-					}
|    | 695|+				}
| 696| 696| 					else
| 697| 697| 						placementSupport.tooltipMessage = translate("Cannot build wall here!");
| 698| 698| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 693| 693| 							inputState = INPUT_NORMAL;
| 694| 694| 						}
| 695| 695| 					}
| 696|    |-					else
|    | 696|+				else
| 697| 697| 						placementSupport.tooltipMessage = translate("Cannot build wall here!");
| 698| 698| 
| 699| 699| 					updateBuildingPlacementPreview();
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 694| 694| 						}
| 695| 695| 					}
| 696| 696| 					else
| 697|    |-						placementSupport.tooltipMessage = translate("Cannot build wall here!");
|    | 697|+					placementSupport.tooltipMessage = translate("Cannot build wall here!");
| 698| 698| 
| 699| 699| 					updateBuildingPlacementPreview();
| 700| 700| 					return true;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 696| 696| 					else
| 697| 697| 						placementSupport.tooltipMessage = translate("Cannot build wall here!");
| 698| 698| 
| 699|    |-					updateBuildingPlacementPreview();
|    | 699|+				updateBuildingPlacementPreview();
| 700| 700| 					return true;
| 701| 701| 				}
| 702| 702| 				else if (ev.button == SDL_BUTTON_RIGHT)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 697| 697| 						placementSupport.tooltipMessage = translate("Cannot build wall here!");
| 698| 698| 
| 699| 699| 					updateBuildingPlacementPreview();
| 700|    |-					return true;
|    | 700|+				return true;
| 701| 701| 				}
| 702| 702| 				else if (ev.button == SDL_BUTTON_RIGHT)
| 703| 703| 				{
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 698| 698| 
| 699| 699| 					updateBuildingPlacementPreview();
| 700| 700| 					return true;
| 701|    |-				}
|    | 701|+			}
| 702| 702| 				else if (ev.button == SDL_BUTTON_RIGHT)
| 703| 703| 				{
| 704| 704| 					// reset to normal input mode
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 699| 699| 					updateBuildingPlacementPreview();
| 700| 700| 					return true;
| 701| 701| 				}
| 702|    |-				else if (ev.button == SDL_BUTTON_RIGHT)
|    | 702|+			else if (ev.button == SDL_BUTTON_RIGHT)
| 703| 703| 				{
| 704| 704| 					// reset to normal input mode
| 705| 705| 					placementSupport.Reset();
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 700| 700| 					return true;
| 701| 701| 				}
| 702| 702| 				else if (ev.button == SDL_BUTTON_RIGHT)
| 703|    |-				{
|    | 703|+			{
| 704| 704| 					// reset to normal input mode
| 705| 705| 					placementSupport.Reset();
| 706| 706| 					updateBuildingPlacementPreview();
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 701| 701| 				}
| 702| 702| 				else if (ev.button == SDL_BUTTON_RIGHT)
| 703| 703| 				{
| 704|    |-					// reset to normal input mode
|    | 704|+				// reset to normal input mode
| 705| 705| 					placementSupport.Reset();
| 706| 706| 					updateBuildingPlacementPreview();
| 707| 707| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 702| 702| 				else if (ev.button == SDL_BUTTON_RIGHT)
| 703| 703| 				{
| 704| 704| 					// reset to normal input mode
| 705|    |-					placementSupport.Reset();
|    | 705|+				placementSupport.Reset();
| 706| 706| 					updateBuildingPlacementPreview();
| 707| 707| 
| 708| 708| 					inputState = INPUT_NORMAL;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 703| 703| 				{
| 704| 704| 					// reset to normal input mode
| 705| 705| 					placementSupport.Reset();
| 706|    |-					updateBuildingPlacementPreview();
|    | 706|+				updateBuildingPlacementPreview();
| 707| 707| 
| 708| 708| 					inputState = INPUT_NORMAL;
| 709| 709| 					return true;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 705| 705| 					placementSupport.Reset();
| 706| 706| 					updateBuildingPlacementPreview();
| 707| 707| 
| 708|    |-					inputState = INPUT_NORMAL;
|    | 708|+				inputState = INPUT_NORMAL;
| 709| 709| 					return true;
| 710| 710| 				}
| 711| 711| 				break;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 706| 706| 					updateBuildingPlacementPreview();
| 707| 707| 
| 708| 708| 					inputState = INPUT_NORMAL;
| 709|    |-					return true;
|    | 709|+				return true;
| 710| 710| 				}
| 711| 711| 				break;
| 712| 712| 		}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 707| 707| 
| 708| 708| 					inputState = INPUT_NORMAL;
| 709| 709| 					return true;
| 710|    |-				}
|    | 710|+			}
| 711| 711| 				break;
| 712| 712| 		}
| 713| 713| 		break;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 708| 708| 					inputState = INPUT_NORMAL;
| 709| 709| 					return true;
| 710| 710| 				}
| 711|    |-				break;
|    | 711|+			break;
| 712| 712| 		}
| 713| 713| 		break;
| 714| 714| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 850| 850| 			break;
| 851| 851| 
| 852| 852| 		case "hotkeydown":
| 853|    |-				if (ev.hotkey.indexOf("selection.group.") == 0)
|    | 853|+			if (ev.hotkey.indexOf("selection.group.") == 0)
| 854| 854| 				{
| 855| 855| 					let now = Date.now();
| 856| 856| 					if (now - doublePressTimer < doublePressTime && ev.hotkey == prevHotkey)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 851| 851| 
| 852| 852| 		case "hotkeydown":
| 853| 853| 				if (ev.hotkey.indexOf("selection.group.") == 0)
| 854|    |-				{
|    | 854|+			{
| 855| 855| 					let now = Date.now();
| 856| 856| 					if (now - doublePressTimer < doublePressTime && ev.hotkey == prevHotkey)
| 857| 857| 					{
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 852| 852| 		case "hotkeydown":
| 853| 853| 				if (ev.hotkey.indexOf("selection.group.") == 0)
| 854| 854| 				{
| 855|    |-					let now = Date.now();
|    | 855|+				let now = Date.now();
| 856| 856| 					if (now - doublePressTimer < doublePressTime && ev.hotkey == prevHotkey)
| 857| 857| 					{
| 858| 858| 						if (ev.hotkey.indexOf("selection.group.select.") == 0)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 853| 853| 				if (ev.hotkey.indexOf("selection.group.") == 0)
| 854| 854| 				{
| 855| 855| 					let now = Date.now();
| 856|    |-					if (now - doublePressTimer < doublePressTime && ev.hotkey == prevHotkey)
|    | 856|+				if (now - doublePressTimer < doublePressTime && ev.hotkey == prevHotkey)
| 857| 857| 					{
| 858| 858| 						if (ev.hotkey.indexOf("selection.group.select.") == 0)
| 859| 859| 						{
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 854| 854| 				{
| 855| 855| 					let now = Date.now();
| 856| 856| 					if (now - doublePressTimer < doublePressTime && ev.hotkey == prevHotkey)
| 857|    |-					{
|    | 857|+				{
| 858| 858| 						if (ev.hotkey.indexOf("selection.group.select.") == 0)
| 859| 859| 						{
| 860| 860| 							var sptr = ev.hotkey.split(".");
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 855| 855| 					let now = Date.now();
| 856| 856| 					if (now - doublePressTimer < doublePressTime && ev.hotkey == prevHotkey)
| 857| 857| 					{
| 858|    |-						if (ev.hotkey.indexOf("selection.group.select.") == 0)
|    | 858|+					if (ev.hotkey.indexOf("selection.group.select.") == 0)
| 859| 859| 						{
| 860| 860| 							var sptr = ev.hotkey.split(".");
| 861| 861| 							performGroup("snap", sptr[3]);
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 856| 856| 					if (now - doublePressTimer < doublePressTime && ev.hotkey == prevHotkey)
| 857| 857| 					{
| 858| 858| 						if (ev.hotkey.indexOf("selection.group.select.") == 0)
| 859|    |-						{
|    | 859|+					{
| 860| 860| 							var sptr = ev.hotkey.split(".");
| 861| 861| 							performGroup("snap", sptr[3]);
| 862| 862| 						}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 7.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 857| 857| 					{
| 858| 858| 						if (ev.hotkey.indexOf("selection.group.select.") == 0)
| 859| 859| 						{
| 860|    |-							var sptr = ev.hotkey.split(".");
|    | 860|+						var sptr = ev.hotkey.split(".");
| 861| 861| 							performGroup("snap", sptr[3]);
| 862| 862| 						}
| 863| 863| 					}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 7.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 858| 858| 						if (ev.hotkey.indexOf("selection.group.select.") == 0)
| 859| 859| 						{
| 860| 860| 							var sptr = ev.hotkey.split(".");
| 861|    |-							performGroup("snap", sptr[3]);
|    | 861|+						performGroup("snap", sptr[3]);
| 862| 862| 						}
| 863| 863| 					}
| 864| 864| 					else
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 859| 859| 						{
| 860| 860| 							var sptr = ev.hotkey.split(".");
| 861| 861| 							performGroup("snap", sptr[3]);
| 862|    |-						}
|    | 862|+					}
| 863| 863| 					}
| 864| 864| 					else
| 865| 865| 					{
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 860| 860| 							var sptr = ev.hotkey.split(".");
| 861| 861| 							performGroup("snap", sptr[3]);
| 862| 862| 						}
| 863|    |-					}
|    | 863|+				}
| 864| 864| 					else
| 865| 865| 					{
| 866| 866| 						var sptr = ev.hotkey.split(".");
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 861| 861| 							performGroup("snap", sptr[3]);
| 862| 862| 						}
| 863| 863| 					}
| 864|    |-					else
|    | 864|+				else
| 865| 865| 					{
| 866| 866| 						var sptr = ev.hotkey.split(".");
| 867| 867| 						performGroup(sptr[2], sptr[3]);
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 862| 862| 						}
| 863| 863| 					}
| 864| 864| 					else
| 865|    |-					{
|    | 865|+				{
| 866| 866| 						var sptr = ev.hotkey.split(".");
| 867| 867| 						performGroup(sptr[2], sptr[3]);
| 868| 868| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 863| 863| 					}
| 864| 864| 					else
| 865| 865| 					{
| 866|    |-						var sptr = ev.hotkey.split(".");
|    | 866|+					var sptr = ev.hotkey.split(".");
| 867| 867| 						performGroup(sptr[2], sptr[3]);
| 868| 868| 
| 869| 869| 						doublePressTimer = now;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 864| 864| 					else
| 865| 865| 					{
| 866| 866| 						var sptr = ev.hotkey.split(".");
| 867|    |-						performGroup(sptr[2], sptr[3]);
|    | 867|+					performGroup(sptr[2], sptr[3]);
| 868| 868| 
| 869| 869| 						doublePressTimer = now;
| 870| 870| 						prevHotkey = ev.hotkey;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 866| 866| 						var sptr = ev.hotkey.split(".");
| 867| 867| 						performGroup(sptr[2], sptr[3]);
| 868| 868| 
| 869|    |-						doublePressTimer = now;
|    | 869|+					doublePressTimer = now;
| 870| 870| 						prevHotkey = ev.hotkey;
| 871| 871| 					}
| 872| 872| 				}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 6.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 867| 867| 						performGroup(sptr[2], sptr[3]);
| 868| 868| 
| 869| 869| 						doublePressTimer = now;
| 870|    |-						prevHotkey = ev.hotkey;
|    | 870|+					prevHotkey = ev.hotkey;
| 871| 871| 					}
| 872| 872| 				}
| 873| 873| 				break;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 4 tabs but found 5.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 868| 868| 
| 869| 869| 						doublePressTimer = now;
| 870| 870| 						prevHotkey = ev.hotkey;
| 871|    |-					}
|    | 871|+				}
| 872| 872| 				}
| 873| 873| 				break;
| 874| 874| 		}
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 869| 869| 						doublePressTimer = now;
| 870| 870| 						prevHotkey = ev.hotkey;
| 871| 871| 					}
| 872|    |-				}
|    | 872|+			}
| 873| 873| 				break;
| 874| 874| 		}
| 875| 875| 		break;
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 3 tabs but found 4.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
| 870| 870| 						prevHotkey = ev.hotkey;
| 871| 871| 					}
| 872| 872| 				}
| 873|    |-				break;
|    | 873|+			break;
| 874| 874| 		}
| 875| 875| 		break;
| 876| 876| 
|    | [NORMAL] ESLintBear (comma-spacing):
|    | A space is required after ','.
|----|    | /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|    |++++| /zpool0/trunk/binaries/data/mods/public/gui/session/input.js
|1602|1602| 	var selectall = Engine.HotkeyIsPressed("selection.offscreen");
|1603|1603| 
|1604|1604| 	// Reset the last idle unit, etc., if the selection type has changed.
|1605|    |-	if (selectall || classes.length != lastIdleClasses.length || !classes.every((v,i) => v === lastIdleClasses[i]))
|    |1605|+	if (selectall || classes.length != lastIdleClasses.length || !classes.every((v, i) => v === lastIdleClasses[i]))
|1606|1606| 		resetIdleUnit();
|1607|1607| 	lastIdleClasses = classes;
|1608|1608| 

binaries/data/mods/public/gui/session/input.js
| 231| »   var·target·=·undefined;
|    | [NORMAL] ESLintBear (no-undef-init):
|    | It's not necessary to initialize 'target' to undefined.

binaries/data/mods/public/gui/session/input.js
| 244| »   var·actionInfo·=·undefined;
|    | [NORMAL] ESLintBear (no-undef-init):
|    | It's not necessary to initialize 'actionInfo' to undefined.

binaries/data/mods/public/gui/session/input.js
| 474| »   switch·(ev.type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
| 501| »   switch·(inputState)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
| 505| »   »   switch·(ev.type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
| 560| »   »   switch·(ev.type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
| 570| »   »   switch·(ev.type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
| 618| »   »   switch·(ev.type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
| 647| »   »   switch·(ev.type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
| 716| »   »   switch·(ev.type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
| 732| ·»   »   »   »   "template":·placementSupport.template,
|    | [NORMAL] ESLintBear (no-mixed-spaces-and-tabs):
|    | Mixed spaces and tabs.

binaries/data/mods/public/gui/session/input.js
| 733| ·»   »   »   »   "x":·placementSupport.position.x,
|    | [NORMAL] ESLintBear (no-mixed-spaces-and-tabs):
|    | Mixed spaces and tabs.

binaries/data/mods/public/gui/session/input.js
| 738| ·»   »   »   });
|    | [NORMAL] ESLintBear (no-mixed-spaces-and-tabs):
|    | Mixed spaces and tabs.

binaries/data/mods/public/gui/session/input.js
| 817| »   switch·(inputState)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
| 820| »   »   switch·(ev.type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
| 922| »   »   switch·(ev.type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
|1011| »   »   switch·(ev.type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
|1025| »   »   »   »   let·action·=·determineAction(ev.x,·ev.y);
|    | [NORMAL] ESLintBear (no-shadow):
|    | 'action' is already declared in the upper scope.

binaries/data/mods/public/gui/session/input.js
|1034| »   »   switch·(ev.type)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
|1058| ·»   »   »   »   »   "template":·placementSupport.template,
|    | [NORMAL] ESLintBear (no-mixed-spaces-and-tabs):
|    | Mixed spaces and tabs.

binaries/data/mods/public/gui/session/input.js
|1059| ·»   »   »   »   »   "x":·placementSupport.position.x,
|    | [NORMAL] ESLintBear (no-mixed-spaces-and-tabs):
|    | Mixed spaces and tabs.

binaries/data/mods/public/gui/session/input.js
|1060| ·»   »   »   »   »   "z":·placementSupport.position.z,
|    | [NORMAL] ESLintBear (no-mixed-spaces-and-tabs):
|    | Mixed spaces and tabs.

binaries/data/mods/public/gui/session/input.js
|1063| ·»   »   »   »   });
|    | [NORMAL] ESLintBear (no-mixed-spaces-and-tabs):
|    | Mixed spaces and tabs.

binaries/data/mods/public/gui/session/input.js
|1123| »   »   »   switch·(ev.hotkey)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
|1553| »   switch·(action)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/session/input.js
| 231| »   var·target·=·undefined;
|    | [NORMAL] JSHintBear:
|    | It's not necessary to initialize 'target' to 'undefined'.

binaries/data/mods/public/gui/session/input.js
| 244| »   var·actionInfo·=·undefined;
|    | [NORMAL] JSHintBear:
|    | It's not necessary to initialize 'actionInfo' to 'undefined'.

binaries/data/mods/public/gui/session/input.js
| 258| »   for·(var·action·of·actions)
|    | [NORMAL] JSHintBear:
|    | 'action' is already defined.

binaries/data/mods/public/gui/session/input.js
| 261| »   »   »   var·r·=·g_UnitActions[action].hotkeyActionCheck(target,·selection);
|    | [NORMAL] JSHintBear:
|    | 'r' is already defined.

binaries/data/mods/public/gui/session/input.js
| 266| »   for·(var·action·of·actions)
|    | [NORMAL] JSHintBear:
|    | 'action' is already defined.

binaries/data/mods/public/gui/session/input.js
| 269| »   »   »   var·r·=·g_UnitActions[action].actionCheck(target,·selection);
|    | [NORMAL] JSHintBear:
|    | 'r' is already defined.

binaries/data/mods/public/gui/session/input.js
| 489| »   »   &&·(ev.button·==·SDL_BUTTON_LEFT·||·ev.button·==·SDL_BUTTON_RIGHT))
|    | [NORMAL] JSHintBear:
|    | Misleading line break before '&&'; readers may interpret this as an expression boundary.

binaries/data/mods/public/gui/session/input.js
| 519| »   »   »   »   var·rect·=·updateBandbox(bandbox,·ev,·true);
|    | [NORMAL] JSHintBear:
|    | 'rect' is already defined.

binaries/data/mods/public/gui/session/input.js
| 522| »   »   »   »   var·ents·=·getPreferredEntities(Engine.PickPlayerEntitiesInRect(rect[0],·rect[1],·rect[2],·rect[3],·g_ViewedPlayer));
|    | [NORMAL] JSHintBear:
|    | 'ents' is already defined.

binaries/data/mods/public/gui/session/input.js
| 679| »   »   »   »   »   var·queued·=·Engine.HotkeyIsPressed("session.queue");
|    | [NORMAL] JSHintBear:
|    | 'queued' is already defined.

binaries/data/mods/public/gui/session/input.js
| 753| »   »   »   »   var·queued·=·Engine.HotkeyIsPressed("session.queue");
|    | [NORMAL] JSHintBear:
|    | 'queued' is already defined.

binaries/data/mods/public/gui/session/input.js
| 866| »   »   »   »   »   »   var·sptr·=·ev.hotkey.split(".");
|    | [NORMAL] JSHintBear:
|    | 'sptr' is already defined.

binaries/data/mods/public/gui/session/input.js
| 882| »   »   »   var·ent·=·Engine.PickEntityAtPoint(ev.x,·ev.y);
|    | [NORMAL] JSHintBear:
|    | 'ent' is already defined.

binaries/data/mods/public/gui/session/input.js
| 908| »   »   »   }
|    | [NORMAL] JSHintBear:
|    | Expected a 'break' statement before 'default'.

binaries/data/mods/public/gui/session/input.js
| 932| »   »   »   var·ent·=·Engine.PickEntityAtPoint(ev.x,·ev.y);
|    | [NORMAL] JSHintBear:
|    | 'ent' is already defined.
Executing section cli...

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/1773/display/redirect

Silier added a subscriber: Silier.

Why this is bad:
It introduces another global variable. (I would say we can just sort g_UnitActions itself, for we have no need of the unsorted variant?)

g_UnitActionsSorted is array of strings so it is not so big of issue.

Init: From non-existent to ~130 microseconds.
OnTick: From ~100 to ~5 microseconds.

I believe on tick gain is more important. Basically this moved first tick time to the init and made almost not existing for the rest so good.

It is ultimately better to sort things once, mainly when they never change like here, so this is basically accepted.

binaries/data/mods/public/gui/session/input.js
242

this is not changing, so should be inlined below

binaries/data/mods/public/gui/session/unit_actions.js
1104

I am a bit thinking about variable name, maybe unitactionssortedkeys ? else one may try something silly.

Freagarach updated this revision to Diff 11681.Apr 15 2020, 5:54 PM
Freagarach marked 2 inline comments as done.
  • g_UnitActionsSorted -> g_UnitActionsSortedKeys.
  • Inlined g_UnitActionsSortedKeys.

(I would say we can just sort g_UnitActions itself, for we have no need of the unsorted variant?)

Apparently one cannot trust the order of an object in JS.

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/2004/display/redirect

Silier accepted this revision.Apr 19 2020, 10:14 AM

(see my previous comment)

This revision is now accepted and ready to land.Apr 19 2020, 10:14 AM
elexis added a subscriber: elexis.Apr 19 2020, 12:16 PM

It introduces another global variable

If a certain or an uncertain dev would finish the class rewrite, it would become a local variable, so it can be considered a global until then that is worth the perf reward.

OnTick: From ~100 to ~5 microseconds.

0.1milliseconds for Object.keys().sort() with an array of 20 items sounds quite a lot, is the number confirmed?

Why this is bad:

There is another disadvantage, that is modders who want to add one item to the object in a second file. They would have to recreate the sorted array. Perhaps that can be optimized, but not a blocking defect.
There is also the disadvantage of having the same value stored in two places in memory (https://en.wikipedia.org/wiki/Single_source_of_truth), so it could be possible that one of the two variables is modified and the other not updated.

Wondering if a deepfreeze would add protection. The entire array could still be replaced, just no keys inserted removed or changed IIRC.

One could also check whether to restructure the entire object. (Just one example, it could become an Array instead of an Object)
But that's a scope creep and more in the scope of a hypothetical rewrite or refactoring.

determineAction

Isn't that function called on every mouse move even? Then the current performance is even worse than a fixed amount of delay per second.
0.1 milliseconds with 100 FPS would then be 10milliseconds per second (perhaps it would be good to confirm the measurement in order to determine the amount of celebration of the patch).

Approval.

binaries/data/mods/public/gui/session/input.js
231

let target;

Freagarach updated this revision to Diff 11693.EditedApr 19 2020, 12:38 PM
Freagarach marked an inline comment as done.
  • Implicit undefined of target.

I had indeed been playing with the idea of not using an object, but way out of scope indeed.
And that could perhaps slow down other parts of the GUI so needs more extensive profiling.

Isn't that function called on every mouse move even?

Yes, that function is called *often*.
I've noted my performance already, so someone else: please confirm.
I used:

let time = Engine.GetMicroseconds();
// Function to measure.
warn(uneval(Engine.GetMicroseconds() - time));

But since there is no function in the determineAction to measure (unless calling the global is less performant that calling a local variable) one could perhaps measure only the initial state and take that as gain?

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/2015/display/redirect

But since there is no function in the determineAction to measure (unless calling the global is less performant that calling a local variable) one could perhaps measure only the initial state and take that as gain?

It would be an assumption that the first Object.keys().sort call has the same performance as the latter ones. (Unlikely, but in theory it could be optimized.)

I measured using:

var start = Engine.GetMicroseconds();
var actions = Object.keys(g_UnitActions);
actions.sort((a, b) => g_UnitActions[a].specificness - g_UnitActions[b].specificness);
warn(Engine.GetMicroseconds() - start);

(This removes the useless slice() as your patch does too)

My results:

129
51
48
101
276
34
35
35
33
36
38
34
41
34
38
38
37
39
49
37
35
34
36
34
38
37
37
33
33
34
36
34
38
38
36
35
50
35
31
34
35
36
35
36
35
35
39
37
38
38
39
43
38
39
37
38
38
39
39
39
38
57
40
38
40
39
43
38
41
33
35
38
29
28
30
34
35
34
37
34
32
30
28
29
30
29
32
40
29
32
31
31
29
38
29
60
29
30
30
30
31
28
28
31
34
34
34
30
32
33
34
35
37
48
36
50
43
41
40

There are one or two ticks outliers after having selected 200+ units.
So basically I can confirm the numbers, that it's 40microseconds instead of 100microseconds can be attributed to the computer, build and whatnot.
(Thanks for the patch and review!)

measured without

let nowx = Engine.GetMicroseconds();
	var actions = Object.keys(g_UnitActions).sort((a, b) => g_UnitActions[a].specificness - g_UnitActions[b].specificness);
	for (let xx of actions) {
		if (g_UnitActions[xx].preSelectedActionCheck) {
			
		}
	}
	let afterx = Engine.GetMicroseconds();
	warn(afterx - nowx);

result

WARNING: 139

WARNING: 52

WARNING: 314

WARNING: 187

WARNING: 65

WARNING: 42

WARNING: 42

WARNING: 123

WARNING: 42

WARNING: 105

WARNING: 41

WARNING: 37

measured with

	let nowx = Engine.GetMicroseconds();
	for (let xx of g_UnitActionsSortedKeys) {
		if (g_UnitActions[xx].preSelectedActionCheck) {
			
		}
	}
	let afterx = Engine.GetMicroseconds();
	warn(afterx - nowx);

result

WARNING: 44

WARNING: 12

WARNING: 13

WARNING: 12

WARNING: 13

WARNING: 17

WARNING: 14

WARNING: 13

WARNING: 13

WARNING: 13

WARNING: 14

WARNING: 12

WARNING: 13

WARNING: 23

WARNING: 12

WARNING: 14

WARNING: 13

Thanks for the confirmation @Angen and @elexis :)

Freagarach edited the summary of this revision. (Show Details)Apr 23 2020, 8:01 AM
This revision was landed with ongoing or failed builds.Apr 25 2020, 8:08 PM
This revision was automatically updated to reflect the committed changes.

Thanks for the commit @Angen :)
And thanks for the review both :D