From e1d5b241f2e878b67378b72d88a4d25fc36b518c Mon Sep 17 00:00:00 2001 From: Acumen Date: Mon, 13 Mar 2006 20:58:21 +0000 Subject: [PATCH] New 'validProperty (propertyString)' function takes care of checking the validity of each subelement in an entity property. (Reduces all that 'if (a && a.b && a.b.c && a.b.c.d)' malarky to 'if (validProperty ("a.b.c.d"))'.) This was SVN commit r3626. --- .../functions_page_session_status_commands.js | 466 +++++++++--------- .../functions_page_session_status_pane.js | 14 +- .../official/gui/test/functions_sim_entity.js | 34 +- 3 files changed, 272 insertions(+), 242 deletions(-) diff --git a/binaries/data/mods/official/gui/test/functions_page_session_status_commands.js b/binaries/data/mods/official/gui/test/functions_page_session_status_commands.js index e4ca72fc9c..6c5f54a5e0 100644 --- a/binaries/data/mods/official/gui/test/functions_page_session_status_commands.js +++ b/binaries/data/mods/official/gui/test/functions_page_session_status_commands.js @@ -159,243 +159,244 @@ function updateTab (tab, type, cellSheet, attribute, attribute2) // * If no value is specified, all entities have this attribute. // attribute2: * For pick: The variable used to store the current item in the pick that has been selected -- placed in the tab (eg selection[0].actions.formation.curr) -console.write ("1st: " + tabCounter + " " + tab + " " + type + " " + cellSheet + " " + attribute + " " + attribute2); - - try - { - // If any items in the list (construction, train, research, etc, need to be updated, update that list.) - if (attribute != undefined - && attribute2 != undefined -// && shouldUpdateStat (attribute) // Can't be this precise, as items in the full batch need to be refreshed when switching between units, - ) + // Store string form of attribute for future reference. + attributeString = attribute; + attribute2String = attribute2; - // Set default values. - if (cellSheet == "") - { - switch (type) - { - case "command": - cellSheet = "Command"; - break; - case "pick": - cellSheet = toTitleCase(tab); - tab = attribute2.toLowerCase(); - // avoid, pick, Stance, .traits.ai.stance.list - break; - default: - cellSheet = "Tab"; - break; - } - } - -console.write ("2nd: " + tabCounter + " " + tab + " " + type + " " + cellSheet + " " + attribute + " " + attribute2); - - // Get tab. - tabObject = getGUIObjectByName ("snStatusPaneCommand" + tabCounter + "_1"); - // Enable tab. - guiUnHide (tabObject.name); - - // Set tab portrait. - setPortrait ("snStatusPaneCommand" + tabCounter + "_1", "IconSheet", cellSheet + "Button", cellGroup[cellSheet][tab].id); - - console.write ("3rd: " + "snStatusPaneCommand" + tabCounter + "_1" + "|" + "IconSheet" + "|" + cellSheet + "Button" + "|" + cellGroup[cellSheet][tab].id); - + // If either attribute is not a valid property, return false. + if ( (validProperty (attributeString)) && (validProperty (attribute2String)) ) + { + // Use the value of the attribute from this point forwards. + attribute = eval (attribute); + attribute2 = eval (attribute2); + +console.write ("1st: " + tabCounter + " " + tab + " " + type + " " + cellSheet + " " + attribute + " " + attribute2); + + // Set default values. + if (cellSheet == "") + { switch (type) { case "command": - // Set tab tooltip. - tooltip = cellGroup[cellSheet][tab].name; - tooltip += " " + cellSheet; + cellSheet = "Command"; break; case "pick": - // Set tab tooltip. - tooltip = cellSheet; - tooltip += " List\nCurrent " + cellSheet + ": " + cellGroup[cellSheet][tab].name; + cellSheet = toTitleCase(tab); + tab = attribute2.toLowerCase(); + // avoid, pick, Stance, .traits.ai.stance.list break; default: - // Set tab tooltip. - tooltip = cellGroup[cellSheet][tab].name; - tooltip += " " + cellSheet; + cellSheet = "Tab"; break; - } - tabObject.tooltip = tooltip; - - switch (type) - { - case "command": - // An array of actions for the command "tabs" can be triggered by clicking the individual commands. We'll set them here. - tabObject.onPress = function (event) - { - } - break; - default: - // Set tab function when user moves mouse over tab. - tabObject.onMouseEnter = function (event) - { - // Click the tab button to toggle visibility of its list. - guiToggle ( "snStatusPaneCommandGroup" + this.name.substring (this.name.lastIndexOf ("d")+1, this.name.lastIndexOf ("_")) ); - } - // Set tab function when user clicks tab. - tabObject.onPress = function (event) - { - // Click the tab button to toggle visibility of its list. - guiToggle ( "snStatusPaneCommandGroup" + this.name.substring (this.name.lastIndexOf ("d")+1, this.name.lastIndexOf ("_")) ); - } - break; - } - - // Get group. - groupObject = getGUIObjectByName ("snStatusPaneCommand" + "Group" + tabCounter); + } + } + +console.write ("2nd: " + tabCounter + " " + tab + " " + type + " " + cellSheet + " " + attribute + " " + attribute2); - // If the list hasn't been hidden (tab is open), and it should have list items (it's not merely a command), - if ( type != "command" ) - { - // Extract item list into an array. - listArray = []; - for ( i in attribute ) + // Get tab. + tabObject = getGUIObjectByName ("snStatusPaneCommand" + tabCounter + "_1"); + // Enable tab. + guiUnHide (tabObject.name); + + // Set tab portrait. + setPortrait ("snStatusPaneCommand" + tabCounter + "_1", "IconSheet", cellSheet + "Button", cellGroup[cellSheet][tab].id); + + console.write ("3rd: " + "snStatusPaneCommand" + tabCounter + "_1" + "|" + "IconSheet" + "|" + cellSheet + "Button" + "|" + cellGroup[cellSheet][tab].id); + + switch (type) + { + case "command": + // Set tab tooltip. + tooltip = cellGroup[cellSheet][tab].name; + tooltip += " " + cellSheet; + break; + case "pick": + // Set tab tooltip. + tooltip = cellSheet; + tooltip += " List\nCurrent " + cellSheet + ": " + cellGroup[cellSheet][tab].name; + break; + default: + // Set tab tooltip. + tooltip = cellGroup[cellSheet][tab].name; + tooltip += " " + cellSheet; + break; + } + tabObject.tooltip = tooltip; + + switch (type) + { + case "command": + // An array of actions for the command "tabs" can be triggered by clicking the individual commands. We'll set them here. + tabObject.onPress = function (event) { - listArray[listArray.length] = i; - // Store any current quantity in the queue for this object. + } + break; + default: + // Set tab function when user moves mouse over tab. + tabObject.onMouseEnter = function (event) + { + // Click the tab button to toggle visibility of its list. + guiToggle ( "snStatusPaneCommandGroup" + this.name.substring (this.name.lastIndexOf ("d")+1, this.name.lastIndexOf ("_")) ); + } + // Set tab function when user clicks tab. + tabObject.onPress = function (event) + { + // Click the tab button to toggle visibility of its list. + guiToggle ( "snStatusPaneCommandGroup" + this.name.substring (this.name.lastIndexOf ("d")+1, this.name.lastIndexOf ("_")) ); + } + break; + } + + // Get group. + groupObject = getGUIObjectByName ("snStatusPaneCommand" + "Group" + tabCounter); + + // If the list hasn't been hidden (tab is open), and it should have list items (it's not merely a command), + if ( type != "command" ) + { + // Extract item list into an array. + listArray = []; + for ( i in attribute ) + { + listArray[listArray.length] = i; + // Store any current quantity in the queue for this object. // if (attribute[i].quantity) // listArray[listArray.length].quantity = attribute[i].quantity; - } + } - // Populate the buttons in this tab's list. - for (createLoop = 1; createLoop < snStatusPaneCommand.list.max; createLoop++) + // Populate the buttons in this tab's list. + for (createLoop = 1; createLoop < snStatusPaneCommand.list.max; createLoop++) + { + // (Skip research list for the moment, since we don't have any portraits for techs. But we should remove the research condition later.) + if (createLoop < listArray.length && type != "command" && tab != "research") { - // (Skip research list for the moment, since we don't have any portraits for techs. But we should remove the research condition later.) - if (createLoop < listArray.length && type != "command" && tab != "research") + // Get name of current button. + listObject = getGUIObjectByName ("snStatusPaneCommand" + tabCounter + "_" + (createLoop+1)); + + switch (type) { - // Get name of current button. - listObject = getGUIObjectByName ("snStatusPaneCommand" + tabCounter + "_" + (createLoop+1)); - - switch (type) - { - case "pick": - // Set tooltip. - listObject.tooltip = toTitleCase(listArray[createLoop]); + case "pick": + // Set tooltip. + listObject.tooltip = toTitleCase(listArray[createLoop]); + + // Set portrait. + setPortrait (listObject.name, + "IconSheet", cellSheet + "Button", cellGroup[cellSheet][listArray[createLoop]].id); - // Set portrait. - setPortrait (listObject.name, - "IconSheet", cellSheet + "Button", cellGroup[cellSheet][listArray[createLoop]].id); - - // Set item function. - listObject.onPress = function (event) + // Set item function. + listObject.onPress = function (event) + { + // Update the tab and the entity's corresponding ".curr" attribute with the "picked" item. + } + break; + default: + // Get name of item to display in list. + itemName = selection[0].traits.id.civ_code + "_" + listArray[createLoop]; + + // Set tooltip. + listObject.tooltip = getEntityTemplate(itemName).traits.id.civ + " " + getEntityTemplate(itemName).traits.id.generic; + + // Store name of entity to display in list in this button's coordinate. + Crd[getCrd (listObject.name, true)].entity = new Object(itemName); + + // Set portrait. + setPortrait (listObject.name, + getEntityTemplate(itemName).traits.id.icon, + "Button" + toTitleCase(selection[0].traits.id.civ_code), + getEntityTemplate(itemName).traits.id.icon_cell); + + // Set item function. + listObject.onPress = function (event) + { + switch (tab) { - // Update the tab and the entity's corresponding ".curr" attribute with the "picked" item. + case "train": + case "research": + // Add this item to the production queue if left-clicked. + // Remove this item from the production queue if right-clicked. + break; + case "barter": + // Buy a quantity of this resource if left-clicked. + // Sell a quantity of this resource if right-clicked. + break; + case "structciv": + case "structmil": + // Select building placement cursor. + startPlacing (Crd[getCrd (this.name, true)].entity); + break; + default: + break; } - break; - default: - // Get name of item to display in list. - itemName = selection[0].traits.id.civ_code + "_" + listArray[createLoop]; - - // Set tooltip. - listObject.tooltip = getEntityTemplate(itemName).traits.id.civ + " " + getEntityTemplate(itemName).traits.id.generic; - - // Store name of entity to display in list in this button's coordinate. - Crd[getCrd (listObject.name, true)].entity = new Object(itemName); - - // Set portrait. - setPortrait (listObject.name, - getEntityTemplate(itemName).traits.id.icon, - "Button" + toTitleCase(selection[0].traits.id.civ_code), - getEntityTemplate(itemName).traits.id.icon_cell); - - // Set item function. - listObject.onPress = function (event) - { - switch (tab) - { - case "train": - case "research": - // Add this item to the production queue if left-clicked. - // Remove this item from the production queue if right-clicked. - break; - case "barter": - // Buy a quantity of this resource if left-clicked. - // Sell a quantity of this resource if right-clicked. - break; - case "structciv": - case "structmil": - // Select building placement cursor. - startPlacing (Crd[getCrd (this.name, true)].entity); - break; - default: - break; - } - } - break; - } - - // Create quantity container in entity's create list if necessary. + } + break; + } + + // Create quantity container in entity's create list if necessary. // if (!attribute[listArray[createLoop]].quantity) // attribute[listArray[createLoop]].quantity = new Object(0); - // Set caption to counter. + // Set caption to counter. // if (attribute[listArray[createLoop]].quantity > 1) // listObject.caption = attribute[listArray[createLoop]].quantity-1; - // Store pointer to quantity in coordinate. + // Store pointer to quantity in coordinate. // Crd[getCrd (listObject.name, true)].quantity = new Object(attribute[listArray[createLoop]].quantity); - - // Reveal portrait. - guiUnHide (listObject.name); - -/* - // Set function that occurs when the button is pressed (left-clicked). - // (Somehow, we also need to do one for right-clicking -- decrement counter and remove item from queue.) - listObject.onPress = function (event) - { - switch (tab) - { - case "StructCiv": - case "StructMil": - // Create building placement cursor. - startPlacing (Crd[getCrd (this.name, true)].entity); - break; - default: - // Attempt to add the entry to the queue. - if (attemptAddToBuildQueue (selection[0], Crd[getCrd (this.name, true)].entity, Crd[getCrd (this.name, true)].tab, Crd[getCrd (this.name, true)].list)) + + // Reveal portrait. + guiUnHide (listObject.name); + +// +// // Set function that occurs when the button is pressed (left-clicked). +// // (Somehow, we also need to do one for right-clicking -- decrement counter and remove item from queue.) +// listObject.onPress = function (event) +// { +// switch (tab) +// { +// case "StructCiv": +// case "StructMil": +// // Create building placement cursor. +// startPlacing (Crd[getCrd (this.name, true)].entity); +// break; +// default: +// // Attempt to add the entry to the queue. +// if (attemptAddToBuildQueue (selection[0], Crd[getCrd (this.name, true)].entity, Crd[getCrd (this.name, true)].tab, Crd[getCrd (this.name, true)].list)) // if (attemptAddToBuildQueue (selection[0], itemName, tab, list)) - { -// // Create quantity container in entity's create list if necessary. - // if (!attribute[Crd[getCrd (this.name, true)].list].quantity) - // attribute[Crd[getCrd (this.name, true)].list].quantity = new Object(0); - // Increment counter. - attribute[Crd[getCrd (this.name, true)].list].quantity++; - // Set caption to counter. - if (attribute[Crd[getCrd (this.name, true)].list].quantity > 1) - this.caption = attribute[Crd[getCrd (this.name, true)].list].quantity-1; - - console.write (this.caption); - } - break; - } - } -*/ - } - else - { - // Conceal this button. - guiHide ("snStatusPaneCommand" + tabCounter + "_" + parseInt(createLoop+1)); - // Ensure it doesn't have a stored entity to display in list. +// { +//// // Create quantity container in entity's create list if necessary. +// // if (!attribute[Crd[getCrd (this.name, true)].list].quantity) +// // attribute[Crd[getCrd (this.name, true)].list].quantity = new Object(0); +// // Increment counter. +// attribute[Crd[getCrd (this.name, true)].list].quantity++; +// // Set caption to counter. +// if (attribute[Crd[getCrd (this.name, true)].list].quantity > 1) +// this.caption = attribute[Crd[getCrd (this.name, true)].list].quantity-1; +// +// console.write (this.caption); +// } +// break; +// } +// } +// + } + else + { + // Conceal this button. + guiHide ("snStatusPaneCommand" + tabCounter + "_" + parseInt(createLoop+1)); + // Ensure it doesn't have a stored entity to display in list. // Crd[getCrd ("snStatusPaneCommand" + tabCounter + "_" + parseInt(createLoop+1), true)].entity = ""; - // Ensure it doesn't have a stored quantity of queued items. + // Ensure it doesn't have a stored quantity of queued items. // Crd[getCrd ("snStatusPaneCommand" + tabCounter + "_" + parseInt(createLoop+1), true)].quantity = 0; - } } } - - // Default the list to closed. - groupObject.hidden = true; - - tabCounter++; - - return true; - } - catch (e if e instanceof TypeError) - { - // Attribute is invalid. Return error. - return false; + } + + // Default the list to closed. + groupObject.hidden = true; + + tabCounter++; + + // Completed tab update successfully. + return true; } + // Invalid property ... Cancel tab update. + return false; } // ==================================================================== @@ -405,32 +406,30 @@ function refreshCommandButtons() // Reset button counter. tabCounter = 1; - if ( selectionChanged && selection[0].actions && shouldUpdateStat ("actions") ) + if ( selectionChanged ) { // Update production lists (both types of Construction, Train). (Tab button, persistent buttons, click them to do things.) - listRoot = selection[0].actions.create.list; - for (listTab in listRoot) + if (validProperty ("selection[0].actions.create.list")) { - if (listTab != "research") // Do research later. - updateTab (listTab, "production", "", listRoot[listTab], ""); - } + listRoot = selection[0].actions.create.list; + for (listTab in listRoot) + { + if (listTab != "research") // Do research later. + updateTab (listTab, "production", "", "listRoot[listTab]", ""); + } + } // Update Barter. (Tab button, persistent buttons, click them to do things.) - if (selection[0].actions && selection[0].actions.barter && selection[0].actions.barter.list) - updateTab ("barter", "production", "", selection[0].actions.barter.list); - + updateTab ("barter", "production", "", "selection[0].actions.barter.list"); + // Update pick lists (formation, stance, trade). (Tab button holds current selection, click a button to select a new option and close the tab.) - if (selection[0].traits && selection[0].traits.formation && selection[0].traits.formation.type && selection[0].traits.formation.curr) - updateTab ("formation", "pick", "", selection[0].traits.formation.type, selection[0].traits.formation.curr); - if (selection[0].traits && selection[0].traits.ai && selection[0].traits.ai.stance && selection[0].traits.ai.stance.list && selection[0].traits.ai.stance.curr) - updateTab ("stance", "pick", "", selection[0].traits.ai.stance.list, selection[0].traits.ai.stance.curr); - if (selection[0].actions && selection[0].actions.trade && selection[0].actions.trade.list && selection[0].actions.trade.curr) - updateTab ("trade", "pick", "", selection[0].actions.trade.list, selection[0].actions.trade.curr); - if (selection[0].actions && selection[0].actions.gate && selection[0].actions.gate.list && selection[0].actions.gate.list.curr) - updateTab ("gate", "pick", "", selection[0].actions.gate.list, selection[0].actions.gate.curr); + updateTab ("formation", "pick", "", "selection[0].traits.formation.type", "selection[0].traits.formation.curr"); + updateTab ("stance", "pick", "", "selection[0].traits.ai.stance.list", "selection[0].traits.ai.stance.curr"); + updateTab ("trade", "pick", "", "selection[0].actions.trade.list", "selection[0].actions.trade.curr"); + updateTab ("gate", "pick", "", "selection[0].actions.gate.list", "selection[0].actions.gate.curr"); // Update research. (Tab button, persistent buttons, click them to do things.) - updateTab ("research", "production", "", selection[0].actions.create.list.research, ""); + updateTab ("research", "production", "", "selection[0].actions.create.list.research", ""); // End of production and pick lists. Store end position. listCounter = tabCounter; @@ -438,12 +437,12 @@ function refreshCommandButtons() // Commands begin from this point. tabCounter = snStatusPaneCommand.split; // Update commands. (Click "tab" button to do something; no list.) - updateTab ("patrol", "command", "", selection[0].actions.patrol, ""); - updateTab ("townbell", "command", "", selection[0].actions.townbell, ""); - updateTab ("rally", "command", "", selection[0].actions.create.rally, ""); - updateTab ("explore", "command", "", selection[0].actions.explore, ""); - updateTab ("retreat", "command", "", selection[0].actions.retreat, ""); - updateTab ("stop", "command", "", selection[0].actions.stop, ""); + updateTab ("patrol", "command", "", "selection[0].actions.patrol", ""); + updateTab ("townbell", "command", "", "selection[0].actions.townbell", ""); + updateTab ("rally", "command", "", "selection[0].actions.create.rally", ""); + updateTab ("explore", "command", "", "selection[0].actions.explore", ""); + updateTab ("retreat", "command", "", "selection[0].actions.retreat", ""); + updateTab ("stop", "command", "", "selection[0].actions.stop", ""); updateTab ("kill", "command", "", "", ""); // End of commands. Store end position. @@ -478,20 +477,19 @@ function refreshCommandButtons() // If there are entities garrisoned in the current entity, if (selection[0].traits.garrison && selection[0].traits.garrison.curr > 0) { - updateTab ("garrison", "production", "", selection, ""); + updateTab ("garrison", "production", "", "selection", ""); } else { // If more than one entity is selected, list them. if (selection.length > 1) - updateTab ("selection", "production", "", selection, ""); + updateTab ("selection", "production", "", "selection", ""); } } // ==================================================================== - // ==================================================================== /* function updateList (listTab, listGroup) diff --git a/binaries/data/mods/official/gui/test/functions_page_session_status_pane.js b/binaries/data/mods/official/gui/test/functions_page_session_status_pane.js index 646bce13d7..0b6bb50901 100644 --- a/binaries/data/mods/official/gui/test/functions_page_session_status_pane.js +++ b/binaries/data/mods/official/gui/test/functions_page_session_status_pane.js @@ -20,7 +20,7 @@ function refreshStatusPane() if ( shouldUpdateStat ( "traits.id.icon" ) ) { // Update portrait - if (selection[0].traits.id.icon) + if (validProperty("selection[0].traits.id.icon")) setPortrait ("snStatusPanePortrait", selection[0].traits.id.icon, toTitleCase(selection[0].traits.id.civ_code), selection[0].traits.id.icon_cell); } @@ -145,17 +145,17 @@ textCaption += '[font=verdana10][color="' + Math.round(selection[0].player.getCo // Update statistic icons. statCurr = 1; - if (selection[0].actions && selection[0].actions.attack && selection[0].actions.attack.melee && selection[0].actions.attack.melee.damage) + if (validProperty ("selection[0].actions.attack.melee.damage")) updateStat ("snStatusPaneStat_", "Attack", "rating", selection[0].actions.attack.melee.damage); - if (selection[0].actions && selection[0].actions.attack && selection[0].actions.attack.melee && selection[0].actions.attack.melee.range) + if (validProperty ("selection[0].actions.attack.melee.range")) updateStat ("snStatusPaneStat_", "Statistic", "range", selection[0].actions.attack.melee.range); - if (selection[0].actions && selection[0].actions.attack && selection[0].actions.attack.ranged && selection[0].actions.attack.ranged.damage) + if (validProperty ("selection[0].actions.attack.ranged.damage")) updateStat ("snStatusPaneStat_", "Attack", "rating", selection[0].actions.attack.ranged.damage); - if (selection[0].actions && selection[0].actions.attack && selection[0].actions.attack.ranged && selection[0].actions.attack.ranged.range) + if (validProperty ("selection[0].actions.attack.ranged.range")) updateStat ("snStatusPaneStat_", "Statistic", "range", selection[0].actions.attack.ranged.range); - if (selection[0].traits && selection[0].traits.armour && selection[0].traits.armour.value) + if (validProperty ("selection[0].traits.armour.value")) updateStat ("snStatusPaneStat_", "Armour", "rating", selection[0].traits.armour.value); - if (selection[0].traits && selection[0].traits.vision && selection[0].traits.vision.los) + if (validProperty ("selection[0].traits.vision.los")) updateStat ("snStatusPaneStat_", "Statistic", "vision", selection[0].traits.vision.los); // Refresh command buttons. diff --git a/binaries/data/mods/official/gui/test/functions_sim_entity.js b/binaries/data/mods/official/gui/test/functions_sim_entity.js index eba2e64250..19fa6681a6 100644 --- a/binaries/data/mods/official/gui/test/functions_sim_entity.js +++ b/binaries/data/mods/official/gui/test/functions_sim_entity.js @@ -201,6 +201,9 @@ function triggerSelectionRun() selection[i].triggerRun(); } } + +// ==================================================================== + function setSelectionRun() { for ( i=0; i< selection.length; i++ ) @@ -209,6 +212,35 @@ function setSelectionRun() } } +// ==================================================================== + +function validProperty (propertyName) +{ + // Accepts a string representing an entity property (eg "selection[0].traits.id.generic") + // and checks if all the elements (selection[0].traits, selection[0].traits.id, etc) are valid properties. + // Returns false if any invalids are found. Returns true if the whole property is valid. + + // An empty string is always successful. + if (propertyName == "") return true; + + // Store elements of the property as an array of strings. + splitArray = propertyName.toString().split ("."); + + // Seek through elements in array. + arrayString = ""; + for (i = 0; i < splitArray.length; i++) + { + // Test each element combination of the string to ensure they are all valid. + if (i > 0) arrayString += "."; + arrayString += splitArray[i]; + + // If the property name is not valid, return false. + if (!(eval (arrayString))) + return false; + } + // If we managed to check them all, every element in the property is valid. Return true. + return true; +} - +// ====================================================================