Torque3D Documentation / _generateds / nodeListManager.cpp

nodeListManager.cpp

Engine/source/environment/nodeListManager.cpp

More...

Public Functions

ConsoleDocClass(NodeListEvent , "@brief Base class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> events used by node editors, like <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">River\n\n</a>" "Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" " @internal" )

Detailed Description

Public Variables

 gClientNodeListManager 
 gServerNodeListManager 
 MODULE_END 
 MODULE_INIT 
 MODULE_SHUTDOWN 

Public Functions

ConsoleDocClass(NodeListEvent , "@brief Base class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> events used by node editors, like <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">River\n\n</a>" "Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" " @internal" )

IMPLEMENT_CO_NETEVENT_V1(NodeListEvent )

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "environment/nodeListManager.h"
 25#include "core/module.h"
 26#include "core/stream/bitStream.h"
 27
 28MODULE_BEGIN( NodeListManager )
 29
 30   MODULE_INIT
 31   {
 32      AssertFatal(gClientNodeListManager == NULL && gServerNodeListManager == NULL, "Error, already initialized the node list manager!");
 33
 34      gClientNodeListManager = new NodeListManager(false);
 35      gServerNodeListManager = new NodeListManager(true);
 36   }
 37
 38   MODULE_SHUTDOWN
 39   {
 40      AssertFatal(gClientNodeListManager != NULL && gServerNodeListManager != NULL, "Error, node list manager not initialized!");
 41
 42      delete gClientNodeListManager;
 43      gClientNodeListManager = NULL;
 44      delete gServerNodeListManager;
 45      gServerNodeListManager = NULL;
 46   }
 47
 48MODULE_END;
 49
 50//-----------------------------------------------------------------------------
 51// NodeListEvent Class
 52//-----------------------------------------------------------------------------
 53
 54NodeListEvent::~NodeListEvent()
 55{
 56   if (mNodeList)
 57   {
 58      // This means the node list wasn't processed
 59      delete mNodeList;
 60   }
 61}
 62
 63void NodeListEvent::pack(NetConnection* conn, BitStream* stream)
 64{
 65   stream->write(mId);
 66   stream->write(mTotalNodes);
 67   stream->write(mLocalListStart);
 68
 69   // NOTE: Child class needs to transmit the nodes
 70}
 71
 72void NodeListEvent::write(NetConnection* conn, BitStream *stream)
 73{
 74   pack(conn, stream);
 75}
 76
 77void NodeListEvent::unpack(NetConnection* conn, BitStream* stream)
 78{
 79   stream->read(&mId);
 80   stream->read(&mTotalNodes);
 81   stream->read(&mLocalListStart);
 82
 83   mNodeList->mId = mId;
 84
 85   // NOTE: Child class needs to populate the local node list
 86}
 87
 88void NodeListEvent::process(NetConnection* conn)
 89{
 90   if (mNodeList)
 91   {
 92      NodeListManager::NodeList* oldList = NULL;
 93
 94      gClientNodeListManager->findListById(mNodeList->mId, &oldList, false);
 95      mergeLists(oldList);
 96
 97      gClientNodeListManager->addNodeList(mNodeList);
 98      mNodeList = NULL;
 99   }
100}
101
102void NodeListEvent::mergeLists(NodeListManager::NodeList* oldList)
103{
104   if (oldList)
105   {
106      if ( !mNodeList->mListComplete)
107      {
108         copyIntoList( oldList );
109
110         // Is the node list now complete?
111         oldList->mTotalValidNodes += mNodeList->mTotalValidNodes;
112         if (oldList->mTotalValidNodes >= mTotalNodes)
113         {
114            oldList->mListComplete = true;
115         }
116
117         delete mNodeList;
118         mNodeList = oldList;
119      }
120   }
121   else
122   {
123      padListToSize();
124   }
125}
126
127IMPLEMENT_CO_NETEVENT_V1(NodeListEvent);
128
129ConsoleDocClass( NodeListEvent,
130   "@brief Base class for events used by node editors, like River\n\n"
131   "Editor use only.\n\n"
132   "@internal"
133);
134//-----------------------------------------------------------------------------
135// NodeListManager Class
136//-----------------------------------------------------------------------------
137
138NodeListManager* gClientNodeListManager = NULL;
139NodeListManager* gServerNodeListManager = NULL;
140
141U32 NodeListManager::smMaximumNodesPerEvent = 20;
142
143//-----------------------------------------------------------------------------
144
145NodeListManager::NodeListManager(const bool isServer)
146{
147   mIsServer = isServer;
148   mNextListId = 0;
149}
150
151NodeListManager::~NodeListManager()
152{
153   clearAllNotifications();
154   clearNodeLists();
155}
156
157void NodeListManager::clearNodeLists()
158{
159   for ( U32 i=0; i<mNodeLists.size(); ++i )
160   {
161      delete mNodeLists[i];
162   }
163   mNodeLists.clear();
164}
165
166U32 NodeListManager::nextListId()
167{
168   U32 id = mNextListId;
169   ++mNextListId;
170   return id;
171}
172
173void NodeListManager::addNodeList( NodeList* list )
174{
175   // Before we store the node list, we should check if anyone has registered
176   // an interest in it, but only if the list is complete.
177   if (list->mListComplete)
178   {
179      if (dispatchNotification( list ))
180      {
181         delete list;
182         return;
183      }
184   }
185
186   // Nothing is registered or the list is not complete, so store the list for later
187   mNodeLists.push_back( list );
188}
189
190bool NodeListManager::findListById(U32 id, NodeList** list, bool completeOnly)
191{
192   *list = NULL;
193
194   for (U32 i=0; i<mNodeLists.size(); ++i)
195   {
196      if (mNodeLists[i]->mId == id)
197      {
198         if (completeOnly && !mNodeLists[i]->mListComplete)
199         {
200            // Found the list, but it is not complete.
201            return false;
202         }
203
204         // Return the node list (complete or not) and remove 
205         // it from our list of lists
206         *list = mNodeLists[i];
207         mNodeLists.erase(i);
208         return true;
209      }
210   }
211
212   return false;
213}
214
215void NodeListManager::clearNotification( U32 listId )
216{
217   for (U32 i=0; i<mNotifyList.size(); ++i)
218   {
219      if (mNotifyList[i]->getListId() == listId)
220      {
221         delete mNotifyList[i];
222         mNotifyList.erase(i);
223         return;
224      }
225   }
226}
227
228void NodeListManager::clearAllNotifications()
229{
230   for (U32 i=0; i<mNotifyList.size(); ++i)
231   {
232      delete mNotifyList[i];
233   }
234   mNotifyList.clear();
235}
236
237void NodeListManager::registerNotification( NodeListNotify* notify )
238{
239   mNotifyList.push_back( notify );
240}
241
242bool NodeListManager::dispatchNotification( U32 listId )
243{
244   // Find the matching list
245   NodeList* list = NULL;
246   for (U32 i=0; i<mNodeLists.size(); ++i)
247   {
248      if (mNodeLists[i]->mId == listId)
249      {
250         list = mNodeLists[i];
251         break;
252      }
253   }
254
255   if (list)
256      return dispatchNotification( list );
257
258   return false;
259}
260
261bool NodeListManager::dispatchNotification( NodeList* list )
262{
263   for (U32 i=0; i<mNotifyList.size(); ++i)
264   {
265      if (mNotifyList[i]->getListId() == list->mId)
266      {
267         mNotifyList[i]->sendNotification( list );
268         delete mNotifyList[i];
269         mNotifyList.erase(i);
270
271         return true;
272      }
273   }
274
275   return false;
276}
277