simDatablock.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _SIM_DATABLOCK_H_
  23. #define _SIM_DATABLOCK_H_
  24. #include "platform/platform.h"
  25. #ifndef _SIM_OBJECT_H_
  26. #include "simObject.h"
  27. #endif
  28. #ifndef _BITSTREAM_H_
  29. #include "io/bitStream.h"
  30. #endif
  31. #ifndef _SIMSET_H_
  32. #include "sim/simSet.h"
  33. #endif
  34. //---------------------------------------------------------------------------
  35. //---------------------------------------------------------------------------
  36. /// Root DataBlock class.
  37. ///
  38. /// @section SimDataBlock_intro Introduction
  39. ///
  40. /// Another powerful aspect of Torque's networking is the datablock. Datablocks
  41. /// are used to provide relatively static information about entities; for instance,
  42. /// what model a weapon should use to display itself, or how heavy a player class is.
  43. ///
  44. /// This gives significant gains in network efficiency, because it means that all
  45. /// the datablocks on a server can be transferred over the network at client
  46. /// connect time, instead of being intertwined with the update code for NetObjects.
  47. ///
  48. /// This makes the network code much simpler overall, as one-time initialization
  49. /// code is segregated from the standard object update code, as well as providing
  50. /// several powerful features, which we will discuss momentarily.
  51. ///
  52. /// @section SimDataBlock_preload preload() and File Downloading
  53. ///
  54. /// Because datablocks are sent over the wire, using SimDataBlockEvent, before
  55. /// gameplay starts in earnest, we gain in several areas. First, we don't have to
  56. /// try to keep up with the game state while working with incomplete information.
  57. /// Second, we can provide the user with a nice loading screen, instead of the more
  58. /// traditional "Connecting..." message. Finally, and most usefully, we can request
  59. /// missing files from the server as we become aware of them, since we are under
  60. /// no obligation to render anything for the user.
  61. ///
  62. /// The mechanism for this is fairly basic. After a datablock is unpacked, the
  63. /// preload() method is called. If it returns false and sets an error, then the
  64. /// network code checks to see if a file (or files) failed to be located by the
  65. /// ResManager; if so, then it requests those files from the server. If preload
  66. /// returns true, then the datablock is considered loaded. If preload returns
  67. /// false and sets no error, then the connection is aborted.
  68. ///
  69. /// Once the file(s) is downloaded, the datablock's preload() method is called again.
  70. /// If it fails with the same error, the connection is aborted. If a new error is
  71. /// returned, then the download-retry process is repeated until the preload works.
  72. ///
  73. /// @section SimDataBlock_guide Guide To Datablock Code
  74. ///
  75. /// To make a datablock subclass, you need to extend three functions:
  76. /// - preload()
  77. /// - packData()
  78. /// - unpackData()
  79. ///
  80. /// packData() and unpackData() simply read or write data to a network stream. If you
  81. /// add any fields, you need to add appropriate calls to read or write. Make sure that
  82. /// the order of reads and writes is the same in both functions. Make sure to call
  83. /// the Parent's version of these methods in every subclass.
  84. ///
  85. /// preload() is a bit more complex; it is responsible for taking the raw data read by
  86. /// unpackData() and processing it into a form useful by the datablock's owning object. For
  87. /// instance, the Player class' datablock, PlayerData, gets handles to commonly used
  88. /// nodes in the player model, as well as resolving handles to textures and other
  89. /// resources. <b>Any</b> code which loads files or performs other actions beyond simply
  90. /// reading the data from the packet, such as validation, must reside in preload().
  91. ///
  92. /// To write your own preload() methods, see any of the existing methods in the codebase; for instance,
  93. /// PlayerData::preload() is an excellent example of error-reporting, data validation, and so forth.
  94. ///
  95. /// @note A useful trick, which is used in several places in the engine, is that of temporarily
  96. /// storing SimObjectIds in the variable which will eventually hold the "real" handle. ShapeImage
  97. /// uses this trick in several pllaces; so do the vehicle classes. See GameBaseData for more on
  98. /// using this trick.
  99. ///
  100. /// @see GameBaseData for some more information on the datablocks used throughout
  101. /// most of the engine.
  102. /// @see http://hosted.tribalwar.com/t2faq/datablocks.shtml for an excellent
  103. /// explanation of the basics of datablocks from script. Note that these comments
  104. /// mostly apply to GameBaseData and its children.
  105. /// @nosubgrouping
  106. class SimDataBlock: public SimObject
  107. {
  108. typedef SimObject Parent;
  109. public:
  110. SimDataBlock();
  111. DECLARE_CONOBJECT(SimDataBlock);
  112. /// @name Datablock Internals
  113. /// @{
  114. protected:
  115. S32 modifiedKey;
  116. public:
  117. static SimObjectId sNextObjectId;
  118. static S32 sNextModifiedKey;
  119. /// Assign a new modified key.
  120. ///
  121. /// Datablocks are assigned a modified key which is updated every time
  122. /// a static field of the datablock is changed. These are gotten from
  123. /// a global store.
  124. static S32 getNextModifiedKey() { return sNextModifiedKey; }
  125. /// Get the modified key for this particular datablock.
  126. S32 getModifiedKey() const { return modifiedKey; }
  127. virtual bool onAdd();
  128. virtual void onRemove();
  129. virtual void onStaticModified(const char* slotName, const char*newValue = NULL);
  130. //void setLastError(const char*);
  131. void assignId();
  132. /// @}
  133. /// @name Datablock Interface
  134. /// @{
  135. ///
  136. virtual void packData(BitStream* stream);
  137. virtual void unpackData(BitStream* stream);
  138. /// Called to prepare the datablock for use, after it has been unpacked.
  139. ///
  140. /// @param server Set if we're running on the server (and therefore don't need to load
  141. /// things like textures or sounds).
  142. /// @param errorBuffer If an error occurs in loading, this is set to a short string describing
  143. /// the error.
  144. /// @returns True if all went well; false if something failed.
  145. ///
  146. /// @see @ref SimDataBlock_preload
  147. virtual bool preload(bool server, char errorBuffer[256]);
  148. /// @}
  149. };
  150. #endif // _SIM_DATABLOCK_H_