Advertisement
Rochet2

Switch vs if vs tricks

Nov 5th, 2015
320
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.22 KB | None | 0 0
  1. http://www.ac-web.org/forums/showthread.php?215486-All-purpose-NPC-duel-reset-enchanter-kill-streak-pvp-titles-teleporter-chat&p=2186359&viewfull=1#post2186359
  2. [QUOTE=Pink<3;2186308]i use if statements a lot in my code to, would you mind explaining what a switch does and when/how to use it, or give me a guide, thanks.[/QUOTE]
  3.  
  4. Nothing wrong with if statements. But if there are a ton of them it may be faster to use a switch.
  5. Consider a chain of a million if-elseif statements. Reaching the last condition would need all the million other conditions checked.
  6. In a switch however the compiler may create a jump table or a hashmap which would reduce the time to a constant so its a lot faster in average and the time to reach any case is the same.
  7. For example if you have an array:
  8. [CODE]int arr[MILLION] = {};[/CODE]
  9. You would probably rather do [CODE]return arr[mycase][/CODE] which instantly returns the result instead of going through all the array elements with a loop like
  10. [CODE]for (int i = 0; i < MILLION; ++i)
  11. if (i == mycase)
  12. return arr[mycase];[/CODE]
  13. The first code takes the same time to get any element (case) from the array (switch) and the second code may take over million times longer (goes through all million if statements).
  14.  
  15. However I would suggest/use a different approach that doesnt use an if or a switch and reduces the amount of code by maybe 50% or more - depends on the code.
  16. You cant always use this, but for the first script here it works pretty well. Note that sender and action are both just numbers. You can use some numbers in the option add code and then when the option is clicked the numbers are passed to the onselect function as action and sender.
  17. This means you can use sender to identify what to do and action as the ID of the pet or spell etc.
  18.  
  19. Example:
  20. [code]
  21. // the menu options
  22. player->ADD_GOSSIP_ITEM(6, "Spider", GOSSIP_SENDER_MAIN, 2053);
  23. player->ADD_GOSSIP_ITEM(6, "Dragonhawk", GOSSIP_SENDER_MAIN, 2042);
  24. player->ADD_GOSSIP_ITEM(6, "Bat", GOSSIP_SENDER_MAIN, 2035);
  25.  
  26. //The select code
  27. case 2053: //Spider
  28. CreatePet(player, creature, 2349);
  29. break;
  30. case 2042: //Dragonhawk
  31. CreatePet(player, creature, 27946);
  32. break;
  33. case 2035: //Bat
  34. CreatePet(player, creature, 28233);
  35. break;[/code]
  36.  
  37. Thats a lot of code for 3 actual actions.
  38. You could do the same like this
  39. [code]
  40. // the menu options. sender 5 is assumed to call CreatePet with the action as pet entry
  41. player->ADD_GOSSIP_ITEM(6, "Spider", 5, 2053);
  42. player->ADD_GOSSIP_ITEM(6, "Dragonhawk", 5, 2042);
  43. player->ADD_GOSSIP_ITEM(6, "Bat", 5, 2035);
  44.  
  45. //The select code
  46. if (sender == 5)
  47. CreatePet(player, creature, action);[/code]
  48. over 9 lines of code was reduced to 2 lines.
  49. Using this approach to create a million pets in the gossip would only require million options coded + the two lines in gossipselect hook.
  50. No massive if or switch statements.
  51. And you can code a different thing to happen if sender is 6 etc.
  52.  
  53. If you have a lot of (static) data instead of a single creature entry or spell entry you could use a container to store it and use uint32 as the key to that container.
  54. Let say you have a vector:
  55.  
  56. [code]
  57. struct Teleport
  58. {
  59. const char* name;
  60. WorldLocation loc;
  61. };
  62. static std::vector<Teleport> teleports = {
  63. // {"name", WorldLocation(mapid, x, y, z, o)},
  64. {"Tele 1", WorldLocation(1, 1.0f, 1.0f, 1.0f, 1.0f)},
  65. {"Tele 2", WorldLocation(1, 1.0f, 1.0f, 1.0f, 1.0f)},
  66. };
  67.  
  68. // the menu options. sender 6 is assumed to call TeleportTo with the action as teleport vector key
  69. for (size_t i = 0; i < teleports.size(); ++i)
  70. player->ADD_GOSSIP_ITEM(6, teleports[i].name, 6, i);
  71.  
  72. //The select code
  73. if (sender == 6 && action < teleports.size())
  74. player->TeleportTo(teleports[action].loc);
  75. [/code]
  76.  
  77. In this code the element's vector index number is passed as the action and this allows you to directly know which vector element holds all the data you want/need to access in the gossip select hook.
  78. Now adding a million teleports would only require adding a million rows - one row to teleports vector for each teleport.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement