simDatablock.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 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. #include "platform/platform.h"
  23. #include "console/simDatablock.h"
  24. #include "console/console.h"
  25. #include "console/consoleInternal.h"
  26. #include "console/engineAPI.h"
  27. #include "T3D/gameBase/gameConnectionEvents.h"
  28. #include "T3D/gameBase/gameConnection.h"
  29. IMPLEMENT_CO_DATABLOCK_V1(SimDataBlock);
  30. SimObjectId SimDataBlock::sNextObjectId = DataBlockObjectIdFirst;
  31. S32 SimDataBlock::sNextModifiedKey = 0;
  32. ConsoleDocClass( SimDataBlock,
  33. "@brief \n"
  34. "@ingroup \n"
  35. "@section Datablock_Networking Datablocks and Networking\n"
  36. "@section Datablock_ClientSide Client-Side Datablocks\n"
  37. );
  38. //-----------------------------------------------------------------------------
  39. SimDataBlock::SimDataBlock()
  40. {
  41. setModDynamicFields(true);
  42. setModStaticFields(true);
  43. }
  44. //-----------------------------------------------------------------------------
  45. bool SimDataBlock::onAdd()
  46. {
  47. Parent::onAdd();
  48. // This initialization is done here, and not in the constructor,
  49. // because some jokers like to construct and destruct objects
  50. // (without adding them to the manager) to check what class
  51. // they are.
  52. modifiedKey = ++sNextModifiedKey;
  53. AssertFatal(sNextObjectId <= DataBlockObjectIdLast,
  54. "Exceeded maximum number of data blocks");
  55. // add DataBlock to the DataBlockGroup unless it is client side ONLY DataBlock
  56. if ( !isClientOnly() )
  57. if (SimGroup* grp = Sim::getDataBlockGroup())
  58. grp->addObject(this);
  59. Sim::getDataBlockSet()->addObject( this );
  60. return true;
  61. }
  62. //-----------------------------------------------------------------------------
  63. void SimDataBlock::assignId()
  64. {
  65. // We don't want the id assigned by the manager, but it may have
  66. // already been assigned a correct data block id.
  67. if ( isClientOnly() )
  68. setId(sNextObjectId++);
  69. }
  70. //-----------------------------------------------------------------------------
  71. void SimDataBlock::onStaticModified(const char* slotName, const char* newValue)
  72. {
  73. modifiedKey = sNextModifiedKey++;
  74. }
  75. //-----------------------------------------------------------------------------
  76. void SimDataBlock::packData(BitStream*)
  77. {
  78. }
  79. //-----------------------------------------------------------------------------
  80. void SimDataBlock::unpackData(BitStream*)
  81. {
  82. }
  83. //-----------------------------------------------------------------------------
  84. bool SimDataBlock::preload(bool, String&)
  85. {
  86. return true;
  87. }
  88. //-----------------------------------------------------------------------------
  89. void SimDataBlock::write(Stream &stream, U32 tabStop, U32 flags)
  90. {
  91. // Only output selected objects if they want that.
  92. if((flags & SelectedOnly) && !isSelected())
  93. return;
  94. stream.writeTabs(tabStop);
  95. char buffer[1024];
  96. // Client side datablocks are created with 'new' while
  97. // regular server datablocks use the 'datablock' keyword.
  98. if ( isClientOnly() )
  99. dSprintf(buffer, sizeof(buffer), "new %s(%s) {\r\n", getClassName(), getName() ? getName() : "");
  100. else
  101. dSprintf(buffer, sizeof(buffer), "datablock %s(%s) {\r\n", getClassName(), getName() ? getName() : "");
  102. stream.write(dStrlen(buffer), buffer);
  103. writeFields(stream, tabStop + 1);
  104. stream.writeTabs(tabStop);
  105. stream.write(4, "};\r\n");
  106. }
  107. //=============================================================================
  108. // API.
  109. //=============================================================================
  110. // MARK: ---- API ----
  111. //-----------------------------------------------------------------------------
  112. DefineConsoleMethod( SimDataBlock, reloadOnLocalClient, void, (),,
  113. "Reload the datablock. This can only be used with a local client configuration." )
  114. {
  115. // Make sure we're running a local client.
  116. GameConnection* localClient = GameConnection::getLocalClientConnection();
  117. if( !localClient )
  118. return;
  119. // Do an in-place pack/unpack/preload.
  120. if( !object->preload( true, NetConnection::getErrorBuffer() ) )
  121. {
  122. Con::errorf( NetConnection::getErrorBuffer() );
  123. return;
  124. }
  125. U8 buffer[ 16384 ];
  126. BitStream stream( buffer, 16384 );
  127. object->packData( &stream );
  128. stream.setPosition(0);
  129. object->unpackData( &stream );
  130. if( !object->preload( false, NetConnection::getErrorBuffer() ) )
  131. {
  132. Con::errorf( NetConnection::getErrorBuffer() );
  133. return;
  134. }
  135. // Trigger a post-apply so that change notifications respond.
  136. object->inspectPostApply();
  137. }
  138. //-----------------------------------------------------------------------------
  139. DefineConsoleFunction( preloadClientDataBlocks, void, (),,
  140. "Preload all datablocks in client mode.\n\n"
  141. "(Server parameter is set to false). This will take some time to complete.")
  142. {
  143. // we go from last to first because we cut 'n pasted the loop from deleteDataBlocks
  144. SimGroup *grp = Sim::getDataBlockGroup();
  145. String errorStr;
  146. for(S32 i = grp->size() - 1; i >= 0; i--)
  147. {
  148. AssertFatal(dynamic_cast<SimDataBlock*>((*grp)[i]), "Doh! non-datablock in datablock group!");
  149. SimDataBlock *obj = (SimDataBlock*)(*grp)[i];
  150. if (!obj->preload(false, errorStr))
  151. Con::errorf("Failed to preload client datablock, %s: %s", obj->getName(), errorStr.c_str());
  152. }
  153. }
  154. //-----------------------------------------------------------------------------
  155. DefineConsoleFunction( deleteDataBlocks, void, (),,
  156. "Delete all the datablocks we've downloaded.\n\n"
  157. "This is usually done in preparation of downloading a new set of datablocks, "
  158. "such as occurs on a mission change, but it's also good post-mission cleanup." )
  159. {
  160. // delete from last to first:
  161. SimGroup *grp = Sim::getDataBlockGroup();
  162. grp->deleteAllObjects();
  163. SimDataBlock::sNextObjectId = DataBlockObjectIdFirst;
  164. SimDataBlock::sNextModifiedKey = 0;
  165. }