⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simbase.h

📁 五行MMORPG引擎系统V1.0
💻 H
📖 第 1 页 / 共 4 页
字号:
   bool isRemoved() const { return mFlags.test(Deleted | Removed); }
   bool isLocked();
   void setLocked( bool b );
   bool isHidden();
   void setHidden(bool b);

   /// @}

   /// @name Sets
   ///
   /// The object must be properly registered before you can add/remove it to/from a set.
   ///
   /// All these functions accept either a name or ID to identify the set you wish
   /// to operate on. Then they call addObject or removeObject on the set, which
   /// sets up appropriate notifications.
   ///
   /// An object may be in multiple sets at a time.
   /// @{
   bool addToSet(SimObjectId);
   bool addToSet(const char *);
   bool removeFromSet(SimObjectId);
   bool removeFromSet(const char *);

   /// @}

   /// @name Serialization
   /// @{

   /// Output the TorqueScript to recreate this object.
   ///
   /// This calls writeFields internally.
   /// @param   stream  Stream to output to.
   /// @param   tabStop Indentation level for this object.
   /// @param   flags   If SelectedOnly is passed here, then
   ///                  only objects marked as selected (using setSelected)
   ///                  will output themselves.
   //virtual void write(Stream &stream, U32 tabStop, U32 flags = 0); /// TGE_Theme

   /// Write the fields of this object in TorqueScript.
   ///
   /// @param   stream  Stream for output.
   /// @param   tabStop Indentation level for the fields.
  // void writeFields(Stream &stream, U32 tabStop); /// TGE_Theme

 
	/// TGE_Theme
   ///                  will output themselves.  If ObjectExists is passed in
   ///                  then the items will be written for an existing object.  EAG - Theme Editor
   virtual void write(Stream &stream, U32 tabStop, U32 flags = 0);

	/// TGE_Theme
   /// Write the fields of this object in TorqueScript.
   ///
   /// @param   stream  Stream for output.
   /// @param   tabStop Indentation level for the fields.
   /// @param   flags   Flag that determines if the field is being written out
   ///                   for a new object or an existing object.  EAG - Theme Editor
   void writeFields(Stream &stream, U32 tabStop, U32 flags = 0);


#ifdef TGE_RPG
   /// 我们很多时候需要重制SimObject对象,duplicate可以做到这一点,
	/// 还好,我们可以调用assignFieldsFrom可以重制所有的字段
	/// 李亦 2006.07.13
   /// @param bWithChildren	如果需要把整个SimObject(即包括所有的子SimObject)都重制一份的话,需要指定为true
   virtual SimObject* duplicate(bool bWithChildren=true,bool bRegister=false);
	
#endif



   /// Copy fields from another object onto this one.
   ///
   /// Objects must be of same type. Everything from obj
   /// will overwrite what's in this object; extra fields
   /// in this object will remain.
   ///
   /// @param   obj Object to copy from.
   void assignFieldsFrom(SimObject *obj);

   /// @}

   /// Return the object's namespace.
   Namespace* getNamespace() { return mNameSpace; }

   /// Get next matching item in namespace.
   ///
   /// This wraps a call to Namespace::tabComplete; it gets the
   /// next thing in the namespace, given a starting value
   /// and a base length of the string. See
   /// Namespace::tabComplete for details.
   const char *tabComplete(const char *prevText, S32 baseLen, bool);

   /// @name Accessors
   /// @{
   bool isSelected() const { return mFlags.test(Selected); }
   bool isExpanded() const { return mFlags.test(Expanded); }
   void setSelected(bool sel) { if(sel) mFlags.set(Selected); else mFlags.clear(Selected); }
   void setExpanded(bool exp) { if(exp) mFlags.set(Expanded); else mFlags.clear(Expanded); }
   void setModDynamicFields(bool dyn) { if(dyn) mFlags.set(ModDynamicFields); else mFlags.clear(ModDynamicFields); }
   void setModStaticFields(bool sta) { if(sta) mFlags.set(ModStaticFields); else mFlags.clear(ModStaticFields); }

   /// @}

   /// @name Initialization
   /// @{

   /// Called to register the object's lights, if any, with the LightManager.
   ///
   /// @param   lm               LightManager to put lights into.
   /// @param   lightingScene   True if we're currently calculating lighting information.
   virtual void registerLights(LightManager * lm, bool lightingScene) {};

   /// @}

   static void initPersistFields();
   DECLARE_CONOBJECT(SimObject);
};

//---------------------------------------------------------------------------
/// Smart SimObject pointer.
///
/// This class keeps track of the book-keeping necessary
/// to keep a registered reference to a SimObject or subclass
/// thereof.
///
/// Normally, if you want the SimObject to be aware that you
/// have a reference to it, you must call SimObject::registerReference()
/// when you create the reference, and SimObject::unregisterReference() when
/// you're done. If you change the reference, you must also register/unregister
/// it. This is a big headache, so this class exists to automatically
/// keep track of things for you.
///
/// @code
///     // Assign an object to the
///     SimObjectPtr<GameBase> mOrbitObject = Sim::findObject("anObject");
///
///     // Use it as a GameBase*.
///     mOrbitObject->getWorldBox().getCenter(&mPosition);
///
///     // And reassign it - it will automatically update the references.
///     mOrbitObject = Sim::findObject("anotherObject");
/// @endcode
template <class T> class SimObjectPtr
{
  private:
   SimObject *mObj;

  public:
   SimObjectPtr() { mObj = 0; }
   SimObjectPtr(T* ptr)
   {
      mObj = ptr;
      if(mObj)
         mObj->registerReference(&mObj);
   }
   SimObjectPtr(const SimObjectPtr<T>& rhs)
   {
      mObj = const_cast<T*>(static_cast<const T*>(rhs));
      if(mObj)
         mObj->registerReference(&mObj);
   }
   SimObjectPtr<T>& operator=(const SimObjectPtr<T>& rhs)
   {
      if(this == &rhs)
         return(*this);
      if(mObj)
         mObj->unregisterReference(&mObj);
      mObj = const_cast<T*>(static_cast<const T*>(rhs));
      if(mObj)
         mObj->registerReference(&mObj);
      return(*this);
   }
   ~SimObjectPtr()
   {
      if(mObj)
         mObj->unregisterReference(&mObj);
   }
   SimObjectPtr<T>& operator= (T *ptr)
   {
      if(mObj != (SimObject *) ptr)
      {
         if(mObj)
            mObj->unregisterReference(&mObj);
         mObj = (SimObject *) ptr;
         if (mObj)
            mObj->registerReference(&mObj);
      }
      return *this;
   }
#if defined(__MWERKS__) && (__MWERKS__ < 0x2400)
   // CW 5.3 seems to get confused comparing SimObjectPtrs...
   bool operator == (const SimObject *ptr) { return mObj == ptr; }
   bool operator != (const SimObject *ptr) { return mObj != ptr; }
#endif
   bool isNull() const   { return mObj == 0; }
   T* operator->() const { return static_cast<T*>(mObj); }
   T& operator*() const  { return *static_cast<T*>(mObj); }
   operator T*() const   { return static_cast<T*>(mObj)? static_cast<T*>(mObj) : 0; }
};

//---------------------------------------------------------------------------
/// Root DataBlock class.
///
/// @section SimDataBlock_intro Introduction
///
/// Another powerful aspect of Torque's networking is the datablock. Datablocks
/// are used to provide relatively static information about entities; for instance,
/// what model a weapon should use to display itself, or how heavy a player class is.
///
/// This gives significant gains in network efficiency, because it means that all
/// the datablocks on a server can be transferred over the network at client
/// connect time, instead of being intertwined with the update code for NetObjects.
///
/// This makes the network code much simpler overall, as one-time initialization
/// code is segregated from the standard object update code, as well as providing
/// several powerful features, which we will discuss momentarily.
///
/// @section SimDataBlock_preload preload() and File Downloading
///
/// Because datablocks are sent over the wire, using SimDataBlockEvent, before
/// gameplay starts in earnest, we gain in several areas. First, we don't have to
/// try to keep up with the game state while working with incomplete information.
/// Second, we can provide the user with a nice loading screen, instead of the more
/// traditional "Connecting..." message. Finally, and most usefully, we can request
/// missing files from the server as we become aware of them, since we are under
/// no obligation to render anything for the user.
///
/// The mechanism for this is fairly basic. After a datablock is unpacked, the
/// preload() method is called. If it returns false and sets an error, then the
/// network code checks to see if a file (or files) failed to be located by the
/// ResManager; if so, then it requests those files from the server. If preload
/// returns true, then the datablock is considered loaded. If preload returns
/// false and sets no error, then the connection is aborted.
///
/// Once the file(s) is downloaded, the datablock's preload() method is called again.
/// If it fails with the same error, the connection is aborted. If a new error is
/// returned, then the download-retry process is repeated until the preload works.
///
/// @section SimDataBlock_guide Guide To Datablock Code
///
/// To make a datablock subclass, you need to extend three functions:
///      - preload()
///      - packData()
///      - unpackData()
///
/// packData() and unpackData() simply read or write data to a network stream. If you
/// add any fields, you need to add appropriate calls to read or write. Make sure that
/// the order of reads and writes is the same in both functions. Make sure to call
/// the Parent's version of these methods in every subclass.
///
/// preload() is a bit more complex; it is responsible for taking the raw data read by
/// unpackData() and processing it into a form useful by the datablock's owning object. For
/// instance, the Player class' datablock, PlayerData, gets handles to commonly used
/// nodes in the player model, as well as resolving handles to textures and other
/// resources. <b>Any</b> code which loads files or performs other actions beyond simply
/// reading the data from the packet, such as validation, must reside in preload().
///
/// To write your own preload() methods, see any of the existing methods in the codebase; for instance,
/// PlayerData::preload() is an excellent example of error-reporting, data validation, and so forth.
///
/// @note A useful trick, which is used in several places in the engine, is that of temporarily
///       storing SimObjectIds in the variable which will eventually hold the "real" handle. ShapeImage
///       uses this trick in several pllaces; so do the vehicle classes. See GameBaseData for more on
///       using this trick.
///
/// @see GameBaseData for some more information on the datablocks used throughout
///      most of the engine.
/// @see http://hosted.tribalwar.com/t2faq/datablocks.shtml for an excellent
///      explanation of the basics of datablocks from script. Note that these comments
///      mostly apply to GameBaseData and its children.
/// @nosubgrouping
class SimDataBlock: public SimObject
{
   typedef SimObject Parent;
public:

   SimDataBlock();
   DECLARE_CONOBJECT(SimDataBlock);

   /// @name Datablock Internals
   /// @{

protected:
   S32  modifiedKey;

  public:
   static SimObjectId sNextObjectId;
   static S32         sNextModifiedKey;

   /// Assign a new modified key.
   ///
   /// Datablocks are assigned a modified key which is updated every time
   /// a static field of the datablock is changed. These are gotten from
   /// a global store.
   static S32 getNextModifiedKey() { return sNextModifiedKey; }

   /// Get the modified key for this particular datablock.
   S32 getModifiedKey() const { return modifiedKey; }

   bool onAdd();
   void onStaticModified(const char* slotName);
   //void setLastError(const char*);
   void assignId();

   /// @}

   /// @name Datablock Interface
   /// @{

   ///
   virtual void packData(BitStream* stream);
   virtual void unpackData(BitStream* stream);

   /// Called to prepare the datablock for use, after it has been unpacked.
   ///
   /// @param  server      Set if we're running on the server (and therefore don't need to load
   ///                     things like textures or sounds).
   /// @param  errorBuffer If an error occurs in loading, this is set to a short string describing
   ///                     the error.
   /// @returns True if all went well; false if something failed.
   ///
   /// @see @ref SimDataBlock_preload
   virtual bool preload(bool server, char errorBuffer[256]);
   /// @}
};

//---------------------------------------------------------------------------
/// A set of SimObjects.
///
/// It is often necessary to keep track of an arbitrary set of SimObjects.
/// For instance, Torque's networking code needs to not only keep track of
/// the set of objects which need to be ghosted, but also the set of objects
/// which must <i>always</i> be ghosted. It does this by working with two
/// sets. The first of these is the RootGroup (which is actually a SimGroup)
/// and the second is the GhostAlwaysSet, which contains objects which must
/// always be ghosted to the client.
///
/// Some general notes on SimSets:
///     - Membership is not exclusive. A SimObject may be a member of multiple
///       SimSets.
///     - A SimSet does not destroy subobjects when it is destroyed.
///     - A SimSet may hold an arbitrary number of objects.
///
/// Using SimSets, the code to work with these two sets becomes
/// relatively straightforward:
///
/// @code
///        // (Example from netObject.cc)
///        // To iterate over all the objects in the Sim:
///        for (SimSetIterator obj(Sim::getRootGroup()); *obj; ++obj)
///        {
///                  NetObject* nobj = dynamic_cast<NetObject*>(*obj);
///
///                 if (nobj)
///                   {
///                     // ... do things ...
///                 }
///         }
///

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -