simSet.cpp
Engine/source/console/simSet.cpp
Public Functions
ConsoleDocClass(SimGroup , "@brief A collection of SimObjects that are owned by the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">group.\n\n</a>" "A <a href="/coding/class/classsimgroup/">SimGroup</a> is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> stricter form of SimSet. SimObjects may only be <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> member " "of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> single <a href="/coding/class/classsimgroup/">SimGroup</a> at <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> time. The <a href="/coding/class/classsimgroup/">SimGroup</a> will automatically enforce " "the single-group-membership rule (ie. adding an object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classsimgroup/">SimGroup</a> will " "cause it <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be removed from its current <a href="/coding/class/classsimgroup/">SimGroup</a>, <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> any).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Deleting <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classsimgroup/">SimGroup</a> will also delete all SimObjects in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SimGroup.\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Create <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classsimgroup/">SimGroup</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> particle <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">emitters\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classsimgroup/">SimGroup</a>(Emitters)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " canSaveDynamicFields = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classparticleemitternode/">ParticleEmitterNode</a>(CrystalEmmiter) {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " active = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " emitter = \"dustEmitter\";\n" " velocity = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " dataBlock = \"GenericSmokeEmitterNode\";\n" " position = \"-61.6276 2.1142 4.45027\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " rotation = \"1 0 0 0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " scale = \"1 1 1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " canSaveDynamicFields = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " };\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classparticleemitternode/">ParticleEmitterNode</a>(Steam1) {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " active = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " emitter = \"SlowSteamEmitter\";\n" " velocity = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " dataBlock = \"GenericSmokeEmitterNode\";\n" " position = \"-25.0458 1.55289 2.51308\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " rotation = \"1 0 0 0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " scale = \"1 1 1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " canSaveDynamicFields = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " };\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Console\n</a>" "@ingroup Scripting" )
ConsoleDocClass(SimSet , "@brief A collection of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SimObjects.\n\n</a>" "It is often necessary <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> keep track of an arbitrary set of SimObjects. " "For instance, Torque 's networking code needs <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> not only keep track of " "the set of objects which need <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be ghosted, but also the set of objects " "which must< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >always</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > be ghosted. It does this by working with two " "sets. The first of these is the RootGroup(which is actually <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classsimgroup/">SimGroup</a>) " "and the second is the GhostAlwaysSet, which contains objects which must " "always be ghosted <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">client.\n\n</a>" "Some general notes on <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SimSets:\n\n</a>" "- Membership is not exclusive. A <a href="/coding/class/classsimobject/">SimObject</a> may be <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> member of multiple " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SimSets.\n\n</a>" "- A <a href="/coding/class/classsimset/">SimSet</a> does not destroy subobjects when it is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">destroyed.\n\n</a>" "- A <a href="/coding/class/classsimset/">SimSet</a> may hold an arbitrary number of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">objects.\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Console\n</a>" " @ingroup Scripting" )
DEFINE_CALLIN(fnSimSet_getCountRecursive , getCountRecursive , SimSet , U32 , (SimSet *set) , "Get the number of direct and indirect child objects contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@return The number of objects contained in the set as well as in other sets contained directly or indirectly in the set." )
DefineEngineMethod(SimSet , acceptsAsChild , bool , (SimObject *obj) , "Test whether the given object may be added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param obj The object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> test <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> potential <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">membership.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the object may be added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the set, false otherwise." )
DefineEngineMethod(SimSet , bringToFront , void , (SimObject *obj) , "Make the given object the first object in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param obj The object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bring <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the frontmost position. Must be contained in the set." )
DefineEngineMethod(SimSet , clear , void , () , "Remove all objects from the set." )
DefineEngineMethod(SimSet , deleteAllObjects , void , () , "() Delete all objects in the set." )
DefineEngineMethod(SimSet , findObjectByInternalName , SimObject * , (const char *internalName, bool searchChildren) , (false) , "Find an object in the set by its internal <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">name.\n</a>" "@param internalName The internal name of the object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> look <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.\n</a>" "@param searchChildren If true, SimSets contained in the set will be recursively searched <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n</a>" " @return The object with the given internal name or 0 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> no match was <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">found.\n</a>" )
DefineEngineMethod(SimSet , getCount , S32 , () , "Get the number of objects contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@return The number of objects contained in the set." )
DefineEngineMethod(SimSet , getFullCount , S32 , () , "() Get the number of direct and indirect child objects contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@return The number of objects contained in the set as well as in other sets contained directly or indirectly in the set." )
DefineEngineMethod(SimSet , getObject , SimObject * , (U32 index) , "Get the object at the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">index.\n</a>" "@param index The object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">index.\n</a>" "@return The object at the given index or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> index is out of range." )
DefineEngineMethod(SimSet , getObjectIndex , S32 , (SimObject *obj) , "Return the index of the given object in this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param obj The object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> return the index. Must be contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@return The index of the object or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the object is not contained in the set." )
DefineEngineMethod(SimSet , getRandom , SimObject * , () , "Return <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> random object from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@return A randomly selected object from the set or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the set is empty." )
DefineEngineMethod(SimSet , isMember , bool , (SimObject *obj) , "Test whether the given object belongs <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param obj The <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the object is contained in the set; false otherwise." )
DefineEngineMethod(SimSet , listObjects , void , () , "Dump <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> list of all objects contained in the set <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console." )
DefineEngineMethod(SimSet , pushToBack , void , (SimObject *obj) , "Make the given object the last object in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param obj The object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bring <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the last position. Must be contained in the set." )
DefineEngineMethod(SimSet , reorderChild , void , (SimObject *child1, SimObject *child2) , "Make sure child1 is ordered right before child2 in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param child1 The first child. The object must already be contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param child2 The second child. The object must already be contained in the set." )
DefineEngineMethod(SimSet , sort , void , (const char *callbackFunction) , "( string callbackFunction ) Sort the objects in the set using the given comparison <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function.\n</a>" "@param callbackFunction Name of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> function that takes two object arguments A and B and returns -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> A is less, 1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> B is less, and 0 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> both are equal." )
DefineEngineStringlyVariadicMethod(SimSet , add , void , 3 , 0 , "( SimObject objects... ) Add the given objects <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param objects The objects <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> add <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the set." )
DefineEngineStringlyVariadicMethod(SimSet , callOnChildren , void , 3 , 0 , "( string method, string args... ) Call <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> method on all objects contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n\n</a>" "@param method The name of the method <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">call.\n</a>" "@param args The arguments <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">method.\n\n</a>" "@note This method recurses into all SimSets that are children <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n\n</a>" "@see callOnChildrenNoRecurse" )
DefineEngineStringlyVariadicMethod(SimSet , callOnChildrenNoRecurse , void , 3 , 0 , "( string method, string args... ) Call <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> method on all objects contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n\n</a>" "@param method The name of the method <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">call.\n</a>" "@param args The arguments <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">method.\n\n</a>" "@note This method does not recurse into child <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SimSets.\n\n</a>" "@see callOnChildren" )
DefineEngineStringlyVariadicMethod(SimSet , remove , void , 3 , 0 , "( SimObject objects... ) Remove the given objects from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param objects The objects <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> remove from the set." )
IMPLEMENT_CALLBACK(SimSet , onObjectAdded , void , (SimObject *object) , (object) , "Called when an object is added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param object The object that was added." )
IMPLEMENT_CALLBACK(SimSet , onObjectRemoved , void , (SimObject *object) , (object) , "Called when an object is removed from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param object The object that was removed." )
Detailed Description
Public Functions
ConsoleDocClass(SimGroup , "@brief A collection of SimObjects that are owned by the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">group.\n\n</a>" "A <a href="/coding/class/classsimgroup/">SimGroup</a> is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> stricter form of SimSet. SimObjects may only be <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> member " "of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> single <a href="/coding/class/classsimgroup/">SimGroup</a> at <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> time. The <a href="/coding/class/classsimgroup/">SimGroup</a> will automatically enforce " "the single-group-membership rule (ie. adding an object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classsimgroup/">SimGroup</a> will " "cause it <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be removed from its current <a href="/coding/class/classsimgroup/">SimGroup</a>, <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> any).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Deleting <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classsimgroup/">SimGroup</a> will also delete all SimObjects in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SimGroup.\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Create <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classsimgroup/">SimGroup</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> particle <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">emitters\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classsimgroup/">SimGroup</a>(Emitters)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " canSaveDynamicFields = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classparticleemitternode/">ParticleEmitterNode</a>(CrystalEmmiter) {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " active = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " emitter = \"dustEmitter\";\n" " velocity = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " dataBlock = \"GenericSmokeEmitterNode\";\n" " position = \"-61.6276 2.1142 4.45027\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " rotation = \"1 0 0 0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " scale = \"1 1 1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " canSaveDynamicFields = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " };\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classparticleemitternode/">ParticleEmitterNode</a>(Steam1) {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " active = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " emitter = \"SlowSteamEmitter\";\n" " velocity = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " dataBlock = \"GenericSmokeEmitterNode\";\n" " position = \"-25.0458 1.55289 2.51308\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " rotation = \"1 0 0 0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " scale = \"1 1 1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " canSaveDynamicFields = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " };\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Console\n</a>" "@ingroup Scripting" )
ConsoleDocClass(SimSet , "@brief A collection of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SimObjects.\n\n</a>" "It is often necessary <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> keep track of an arbitrary set of SimObjects. " "For instance, Torque 's networking code needs <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> not only keep track of " "the set of objects which need <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be ghosted, but also the set of objects " "which must< <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> >always</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a> > be ghosted. It does this by working with two " "sets. The first of these is the RootGroup(which is actually <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classsimgroup/">SimGroup</a>) " "and the second is the GhostAlwaysSet, which contains objects which must " "always be ghosted <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">client.\n\n</a>" "Some general notes on <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SimSets:\n\n</a>" "- Membership is not exclusive. A <a href="/coding/class/classsimobject/">SimObject</a> may be <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> member of multiple " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SimSets.\n\n</a>" "- A <a href="/coding/class/classsimset/">SimSet</a> does not destroy subobjects when it is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">destroyed.\n\n</a>" "- A <a href="/coding/class/classsimset/">SimSet</a> may hold an arbitrary number of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">objects.\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Console\n</a>" " @ingroup Scripting" )
DEFINE_CALLIN(fnSimSet_getCountRecursive , getCountRecursive , SimSet , U32 , (SimSet *set) , "Get the number of direct and indirect child objects contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@return The number of objects contained in the set as well as in other sets contained directly or indirectly in the set." )
DefineEngineMethod(SimSet , acceptsAsChild , bool , (SimObject *obj) , "Test whether the given object may be added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param obj The object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> test <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> potential <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">membership.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the object may be added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the set, false otherwise." )
DefineEngineMethod(SimSet , bringToFront , void , (SimObject *obj) , "Make the given object the first object in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param obj The object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bring <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the frontmost position. Must be contained in the set." )
DefineEngineMethod(SimSet , clear , void , () , "Remove all objects from the set." )
DefineEngineMethod(SimSet , deleteAllObjects , void , () , "() Delete all objects in the set." )
DefineEngineMethod(SimSet , findObjectByInternalName , SimObject * , (const char *internalName, bool searchChildren) , (false) , "Find an object in the set by its internal <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">name.\n</a>" "@param internalName The internal name of the object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> look <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">for.\n</a>" "@param searchChildren If true, SimSets contained in the set will be recursively searched <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n</a>" " @return The object with the given internal name or 0 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> no match was <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">found.\n</a>" )
DefineEngineMethod(SimSet , getCount , S32 , () , "Get the number of objects contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@return The number of objects contained in the set." )
DefineEngineMethod(SimSet , getFullCount , S32 , () , "() Get the number of direct and indirect child objects contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@return The number of objects contained in the set as well as in other sets contained directly or indirectly in the set." )
DefineEngineMethod(SimSet , getObject , SimObject * , (U32 index) , "Get the object at the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">index.\n</a>" "@param index The object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">index.\n</a>" "@return The object at the given index or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> index is out of range." )
DefineEngineMethod(SimSet , getObjectIndex , S32 , (SimObject *obj) , "Return the index of the given object in this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param obj The object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> which <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> return the index. Must be contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@return The index of the object or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the object is not contained in the set." )
DefineEngineMethod(SimSet , getRandom , SimObject * , () , "Return <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> random object from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@return A randomly selected object from the set or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the set is empty." )
DefineEngineMethod(SimSet , isMember , bool , (SimObject *obj) , "Test whether the given object belongs <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param obj The <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the object is contained in the set; false otherwise." )
DefineEngineMethod(SimSet , listObjects , void , () , "Dump <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> list of all objects contained in the set <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the console." )
DefineEngineMethod(SimSet , pushToBack , void , (SimObject *obj) , "Make the given object the last object in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param obj The object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> bring <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the last position. Must be contained in the set." )
DefineEngineMethod(SimSet , reorderChild , void , (SimObject *child1, SimObject *child2) , "Make sure child1 is ordered right before child2 in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param child1 The first child. The object must already be contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param child2 The second child. The object must already be contained in the set." )
DefineEngineMethod(SimSet , sort , void , (const char *callbackFunction) , "( string callbackFunction ) Sort the objects in the set using the given comparison <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function.\n</a>" "@param callbackFunction Name of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> function that takes two object arguments A and B and returns -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> A is less, 1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> B is less, and 0 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> both are equal." )
DefineEngineStringlyVariadicMethod(SimSet , add , void , 3 , 0 , "( SimObject objects... ) Add the given objects <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param objects The objects <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> add <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the set." )
DefineEngineStringlyVariadicMethod(SimSet , callOnChildren , void , 3 , 0 , "( string method, string args... ) Call <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> method on all objects contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n\n</a>" "@param method The name of the method <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">call.\n</a>" "@param args The arguments <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">method.\n\n</a>" "@note This method recurses into all SimSets that are children <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n\n</a>" "@see callOnChildrenNoRecurse" )
DefineEngineStringlyVariadicMethod(SimSet , callOnChildrenNoRecurse , void , 3 , 0 , "( string method, string args... ) Call <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> method on all objects contained in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n\n</a>" "@param method The name of the method <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">call.\n</a>" "@param args The arguments <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">method.\n\n</a>" "@note This method does not recurse into child <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SimSets.\n\n</a>" "@see callOnChildren" )
DefineEngineStringlyVariadicMethod(SimSet , remove , void , 3 , 0 , "( SimObject objects... ) Remove the given objects from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param objects The objects <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> remove from the set." )
IMPLEMENT_CALLBACK(SimSet , onObjectAdded , void , (SimObject *object) , (object) , "Called when an object is added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param object The object that was added." )
IMPLEMENT_CALLBACK(SimSet , onObjectRemoved , void , (SimObject *object) , (object) , "Called when an object is removed from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set.\n</a>" "@param object The object that was removed." )
IMPLEMENT_CONOBJECT(SimGroup )
IMPLEMENT_CONOBJECT_CHILDREN(SimSet )
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 "platform/platform.h" 25#include "console/simSet.h" 26 27#include "core/stringTable.h" 28#include "console/console.h" 29#include "console/engineAPI.h" 30#include "core/stream/fileStream.h" 31#include "sim/actionMap.h" 32#include "core/fileObject.h" 33#include "console/consoleInternal.h" 34#include "console/engineAPI.h" 35#include "platform/profiler.h" 36#include "console/typeValidators.h" 37#include "core/frameAllocator.h" 38#include "math/mMathFn.h" 39 40 41IMPLEMENT_CONOBJECT_CHILDREN( SimSet ); 42IMPLEMENT_CONOBJECT( SimGroup ); 43 44ConsoleDocClass( SimSet, 45 "@brief A collection of SimObjects.\n\n" 46 47 "It is often necessary to keep track of an arbitrary set of SimObjects. " 48 "For instance, Torque's networking code needs to not only keep track of " 49 "the set of objects which need to be ghosted, but also the set of objects " 50 "which must <i>always</i> be ghosted. It does this by working with two " 51 "sets. The first of these is the RootGroup (which is actually a SimGroup) " 52 "and the second is the GhostAlwaysSet, which contains objects which must " 53 "always be ghosted to the client.\n\n" 54 55 "Some general notes on SimSets:\n\n" 56 "- Membership is not exclusive. A SimObject may be a member of multiple " 57 "SimSets.\n\n" 58 "- A SimSet does not destroy subobjects when it is destroyed.\n\n" 59 "- A SimSet may hold an arbitrary number of objects.\n\n" 60 61 "@ingroup Console\n" 62 "@ingroup Scripting" 63); 64ConsoleDocClass( SimGroup, 65 "@brief A collection of SimObjects that are owned by the group.\n\n" 66 67 "A SimGroup is a stricter form of SimSet. SimObjects may only be a member " 68 "of a single SimGroup at a time. The SimGroup will automatically enforce " 69 "the single-group-membership rule (ie. adding an object to a SimGroup will " 70 "cause it to be removed from its current SimGroup, if any).\n\n" 71 72 "Deleting a SimGroup will also delete all SimObjects in the SimGroup.\n\n" 73 74 "@tsexample\n" 75 "// Create a SimGroup for particle emitters\n" 76 "new SimGroup(Emitters)\n" 77 "{\n" 78 " canSaveDynamicFields = \"1\";\n\n" 79 " new ParticleEmitterNode(CrystalEmmiter) {\n" 80 " active = \"1\";\n" 81 " emitter = \"dustEmitter\";\n" 82 " velocity = \"1\";\n" 83 " dataBlock = \"GenericSmokeEmitterNode\";\n" 84 " position = \"-61.6276 2.1142 4.45027\";\n" 85 " rotation = \"1 0 0 0\";\n" 86 " scale = \"1 1 1\";\n" 87 " canSaveDynamicFields = \"1\";\n" 88 " };\n\n" 89 " new ParticleEmitterNode(Steam1) {\n" 90 " active = \"1\";\n" 91 " emitter = \"SlowSteamEmitter\";\n" 92 " velocity = \"1\";\n" 93 " dataBlock = \"GenericSmokeEmitterNode\";\n" 94 " position = \"-25.0458 1.55289 2.51308\";\n" 95 " rotation = \"1 0 0 0\";\n" 96 " scale = \"1 1 1\";\n" 97 " canSaveDynamicFields = \"1\";\n" 98 " };\n" 99 "};\n\n" 100 "@endtsexample\n\n" 101 "@ingroup Console\n" 102 "@ingroup Scripting" 103); 104 105IMPLEMENT_CALLBACK( SimSet, onObjectAdded, void, ( SimObject* object ), ( object ), 106 "Called when an object is added to the set.\n" 107 "@param object The object that was added." ); 108IMPLEMENT_CALLBACK( SimSet, onObjectRemoved, void, ( SimObject* object ), ( object ), 109 "Called when an object is removed from the set.\n" 110 "@param object The object that was removed." ); 111 112 113//============================================================================= 114// SimSet. 115//============================================================================= 116// MARK: ---- SimSet ---- 117 118//----------------------------------------------------------------------------- 119 120SimSet::SimSet() 121{ 122 VECTOR_SET_ASSOCIATION(mObjectList); 123 mMutex = Mutex::createMutex(); 124} 125 126//----------------------------------------------------------------------------- 127 128SimSet::~SimSet() 129{ 130 Mutex::destroyMutex( mMutex ); 131} 132 133//----------------------------------------------------------------------------- 134 135void SimSet::addObject( SimObject* obj ) 136{ 137 // Prevent SimSet being added to itself. 138 if( obj == this ) 139 return; 140 141 lock(); 142 143 const bool added = mObjectList.pushBack( obj ); 144 if( added ) 145 deleteNotify( obj ); 146 147 unlock(); 148 149 if( added ) 150 { 151 getSetModificationSignal().trigger( SetObjectAdded, this, obj ); 152 if( obj->isProperlyAdded() ) 153 onObjectAdded_callback( obj ); 154 } 155} 156 157//----------------------------------------------------------------------------- 158 159void SimSet::removeObject( SimObject* obj ) 160{ 161 lock(); 162 163 const bool removed = mObjectList.remove( obj ); 164 if( removed ) 165 clearNotify( obj ); 166 167 unlock(); 168 169 if( removed ) 170 { 171 getSetModificationSignal().trigger( SetObjectRemoved, this, obj ); 172 if( obj->isProperlyAdded() ) 173 onObjectRemoved_callback( obj ); 174 } 175} 176 177//----------------------------------------------------------------------------- 178 179void SimSet::pushObject( SimObject* obj ) 180{ 181 if( obj == this ) 182 return; 183 184 lock(); 185 186 bool added = mObjectList.pushBackForce( obj ); 187 if( added ) 188 deleteNotify( obj ); 189 190 unlock(); 191 192 if( added ) 193 { 194 getSetModificationSignal().trigger( SetObjectAdded, this, obj ); 195 if( obj->isProperlyAdded() ) 196 onObjectAdded_callback( obj ); 197 } 198} 199 200//----------------------------------------------------------------------------- 201 202void SimSet::popObject() 203{ 204 if(mObjectList.empty() ) 205 { 206 AssertWarn(false, "Stack underflow in SimSet::popObject"); 207 return; 208 } 209 210 lock(); 211 SimObject* object = mObjectList.last(); 212 mObjectList.pop_back(); 213 214 clearNotify( object ); 215 unlock(); 216 217 getSetModificationSignal().trigger( SetObjectRemoved, this, object ); 218 if( object->isProperlyAdded() ) 219 onObjectRemoved_callback( object ); 220} 221 222//----------------------------------------------------------------------------- 223 224void SimSet::scriptSort( const String &scriptCallbackFn ) 225{ 226 lock(); 227 mObjectList.scriptSort( scriptCallbackFn ); 228 unlock(); 229} 230 231//----------------------------------------------------------------------------- 232 233void SimSet::callOnChildren( const String &method, S32 argc, ConsoleValueRef argv[], bool executeOnChildGroups ) 234{ 235 // Prep the arguments for the console exec... 236 // Make sure and leave args[1] empty. 237 ConsoleValueRef args[21] = { }; 238 ConsoleValue name_method; 239 name_method.setStackStringValue(method.c_str()); 240 args[0] = ConsoleValueRef::fromValue(&name_method); 241 242 for (S32 i = 0; i < argc; i++) 243 args[i + 2] = argv[i]; 244 245 for( iterator i = begin(); i != end(); i++ ) 246 { 247 SimObject *childObj = static_cast<SimObject*>(*i); 248 249 if( childObj->isMethod( method.c_str() ) ) 250 Con::execute(childObj, argc + 2, args); 251 252 if( executeOnChildGroups ) 253 { 254 SimSet* childSet = dynamic_cast<SimSet*>(*i); 255 if ( childSet ) 256 childSet->callOnChildren( method, argc, argv, executeOnChildGroups ); 257 } 258 } 259} 260 261//----------------------------------------------------------------------------- 262 263U32 SimSet::sizeRecursive() 264{ 265 U32 count = 0; 266 267 for ( iterator i = begin(); i != end(); i++ ) 268 { 269 count++; 270 271 SimSet* childSet = dynamic_cast<SimSet*>(*i); 272 if ( childSet ) 273 count += childSet->sizeRecursive(); 274 } 275 276 return count; 277} 278 279//----------------------------------------------------------------------------- 280 281bool SimSet::reOrder( SimObject *obj, SimObject *target ) 282{ 283 MutexHandle handle; 284 handle.lock(mMutex); 285 286 iterator itrS, itrD; 287 if ( (itrS = find(begin(),end(),obj)) == end() ) 288 { 289 // object must be in list 290 return false; 291 } 292 293 if ( obj == target ) 294 { 295 // don't reorder same object but don't indicate error 296 return true; 297 } 298 299 if ( !target ) 300 { 301 // if no target, then put to back of list 302 303 // don't move if already last object 304 if ( itrS != (end()-1) ) 305 { 306 // remove object from its current location and push to back of list 307 mObjectList.erase(itrS); 308 mObjectList.push_back(obj); 309 } 310 } 311 else 312 { 313 // if target, insert object in front of target 314 if ( (itrD = find(begin(),end(),target)) == end() ) 315 // target must be in list 316 return false; 317 318 mObjectList.erase(itrS); 319 320 // once itrS has been erased, itrD won't be pointing at the 321 // same place anymore - re-find... 322 itrD = find(begin(),end(),target); 323 mObjectList.insert(itrD, obj); 324 } 325 326 return true; 327} 328 329//----------------------------------------------------------------------------- 330 331void SimSet::onDeleteNotify(SimObject *object) 332{ 333 removeObject(object); 334 Parent::onDeleteNotify(object); 335} 336 337//----------------------------------------------------------------------------- 338 339void SimSet::onRemove() 340{ 341 MutexHandle handle; 342 handle.lock( mMutex ); 343 344 if( !mObjectList.empty() ) 345 { 346 mObjectList.sortId(); 347 348 // This backwards iterator loop doesn't work if the 349 // list is empty, check the size first. 350 351 for( SimObjectList::iterator ptr = mObjectList.end() - 1; 352 ptr >= mObjectList.begin(); ptr -- ) 353 clearNotify( *ptr ); 354 } 355 356 handle.unlock(); 357 358 Parent::onRemove(); 359} 360 361//----------------------------------------------------------------------------- 362 363void SimSet::write(Stream &stream, U32 tabStop, U32 flags) 364{ 365 MutexHandle handle; 366 handle.lock(mMutex); 367 368 // export selected only? 369 if((flags & SelectedOnly) && !isSelected()) 370 { 371 for(U32 i = 0; i < size(); i++) 372 (*this)[i]->write(stream, tabStop, flags); 373 374 return; 375 376 } 377 378 stream.writeTabs( tabStop ); 379 char buffer[ 2048 ]; 380 const U32 bufferWriteLen = dSprintf( buffer, sizeof( buffer ), "new %s(%s) {\r\n", getClassName(), getName() && !( flags & NoName ) ? getName() : "" ); 381 stream.write( bufferWriteLen, buffer ); 382 writeFields( stream, tabStop + 1 ); 383 384 if(size()) 385 { 386 stream.write(2, "\r\n"); 387 for(U32 i = 0; i < size(); i++) 388 { 389 SimObject* child = ( *this )[ i ]; 390 if( child->getCanSave() ) 391 child->write(stream, tabStop + 1, flags); 392 } 393 } 394 395 stream.writeTabs(tabStop); 396 stream.write(4, "};\r\n"); 397} 398 399//----------------------------------------------------------------------------- 400 401void SimSet::clear() 402{ 403 lock(); 404 405 while( !empty() ) 406 popObject(); 407 408 unlock(); 409 410 getSetModificationSignal().trigger( SetCleared, this, NULL ); 411} 412 413//----------------------------------------------------------------------------- 414 415//UNSAFE 416void SimSet::deleteAllObjects() 417{ 418 lock(); 419 while( !empty() ) 420 { 421 SimObject* object = mObjectList.last(); 422 mObjectList.pop_back(); 423 424 object->deleteObject(); 425 } 426 unlock(); 427} 428 429//----------------------------------------------------------------------------- 430 431SimObject* SimSet::findObject( SimObject* object ) 432{ 433 bool found = false; 434 lock(); 435 for( SimSet::iterator iter = begin(); iter != end(); ++ iter ) 436 if( *iter == object ) 437 { 438 found = true; 439 break; 440 } 441 unlock(); 442 443 if( found ) 444 return object; 445 446 return NULL; 447} 448 449//----------------------------------------------------------------------------- 450 451SimObject* SimSet::findObject( const char *namePath ) 452{ 453 // find the end of the object name 454 S32 len; 455 for(len = 0; namePath[len] != 0 && namePath[len] != '/'; len++) 456 ; 457 458 StringTableEntry stName = StringTable->lookupn(namePath, len); 459 if(!stName) 460 return NULL; 461 462 lock(); 463 for(SimSet::iterator i = begin(); i != end(); i++) 464 { 465 if((*i)->getName() == stName) 466 { 467 unlock(); 468 if(namePath[len] == 0) 469 return *i; 470 return (*i)->findObject(namePath + len + 1); 471 } 472 } 473 unlock(); 474 return NULL; 475} 476 477//----------------------------------------------------------------------------- 478 479SimObject* SimSet::findObjectByInternalName(StringTableEntry internalName, bool searchChildren) 480{ 481 iterator i; 482 for (i = begin(); i != end(); i++) 483 { 484 SimObject *childObj = static_cast<SimObject*>(*i); 485 if(childObj->getInternalName() == internalName) 486 return childObj; 487 else if (searchChildren) 488 { 489 SimSet* childSet = dynamic_cast<SimSet*>(*i); 490 if (childSet) 491 { 492 SimObject* found = childSet->findObjectByInternalName(internalName, searchChildren); 493 if (found) return found; 494 } 495 } 496 } 497 498 return NULL; 499} 500 501//----------------------------------------------------------------------------- 502 503SimObject* SimSet::findObjectByLineNumber(const char* fileName, S32 declarationLine, bool searchChildren) 504{ 505 if (!fileName) 506 return NULL; 507 508 if (declarationLine < 0) 509 return NULL; 510 511 StringTableEntry fileEntry = StringTable->insert(fileName); 512 513 for (iterator i = begin(); i != end(); i++) 514 { 515 SimObject *childObj = static_cast<SimObject*>(*i); 516 517 if(childObj->getFilename() == fileEntry && childObj->getDeclarationLine() == declarationLine) 518 return childObj; 519 else if (searchChildren) 520 { 521 SimSet* childSet = dynamic_cast<SimSet*>(*i); 522 523 if (childSet) 524 { 525 SimObject* found = childSet->findObjectByLineNumber(fileName, declarationLine, searchChildren); 526 if (found) 527 return found; 528 } 529 } 530 } 531 532 return NULL; 533} 534 535//----------------------------------------------------------------------------- 536 537SimObject* SimSet::getRandom() 538{ 539 if (size() > 0) 540 return mObjectList[mRandI(0, size() - 1)]; 541 542 return NULL; 543} 544 545//----------------------------------------------------------------------------- 546 547SimSet* SimSet::clone() 548{ 549 // Clone the set object. 550 551 SimObject* object = Parent::clone(); 552 SimSet* set = dynamic_cast< SimSet* >( object ); 553 if( !set ) 554 { 555 object->deleteObject(); 556 return NULL; 557 } 558 559 // Add all object in the set. 560 561 for( iterator iter = begin(); iter != end(); ++ iter ) 562 set->addObject( *iter ); 563 564 return set; 565} 566 567//----------------------------------------------------------------------------- 568 569inline void SimSetIterator::Stack::push_back(SimSet* set) 570{ 571 increment(); 572 last().set = set; 573 last().itr = set->begin(); 574} 575 576//----------------------------------------------------------------------------- 577 578SimSetIterator::SimSetIterator(SimSet* set) 579{ 580 VECTOR_SET_ASSOCIATION(stack); 581 582 if (!set->empty()) 583 stack.push_back(set); 584} 585 586//----------------------------------------------------------------------------- 587 588SimObject* SimSetIterator::operator++() 589{ 590 SimSet* set; 591 if ((set = dynamic_cast<SimSet*>(*stack.last().itr)) != 0) 592 { 593 if (!set->empty()) 594 { 595 stack.push_back(set); 596 return *stack.last().itr; 597 } 598 } 599 600 while (++stack.last().itr == stack.last().set->end()) 601 { 602 stack.pop_back(); 603 if (stack.empty()) 604 return 0; 605 } 606 return *stack.last().itr; 607} 608 609//============================================================================= 610// SimGroup. 611//============================================================================= 612// MARK: ---- SimGroup ---- 613 614//----------------------------------------------------------------------------- 615 616SimGroup::~SimGroup() 617{ 618 for( iterator itr = begin(); itr != end(); itr ++ ) 619 mNameDictionary.remove(*itr); 620} 621 622//----------------------------------------------------------------------------- 623 624void SimGroup::_addObject( SimObject* obj, bool forcePushBack ) 625{ 626 // Make sure we aren't adding ourself. This isn't the most robust check 627 // but it should be good enough to prevent some self-foot-shooting. 628 if( obj == this ) 629 { 630 Con::errorf( "SimGroup::addObject - (%d) can't add self!", getIdString() ); 631 return; 632 } 633 634 if( obj->getGroup() == this ) 635 return; 636 637 lock(); 638 639 obj->incRefCount(); 640 641 if( obj->getGroup() ) 642 obj->getGroup()->removeObject( obj ); 643 644 if( forcePushBack ? mObjectList.pushBack( obj ) : mObjectList.pushBackForce( obj ) ) 645 { 646 mNameDictionary.insert( obj ); 647 obj->mGroup = this; 648 649 obj->onGroupAdd(); 650 651 getSetModificationSignal().trigger( SetObjectAdded, this, obj ); 652 if( obj->isProperlyAdded() ) 653 onObjectAdded_callback( obj ); 654 } 655 else 656 obj->decRefCount(); 657 658 unlock(); 659 660 // SimObjects will automatically remove them from their group 661 // when deleted so we don't hook up a delete notification. 662} 663 664//----------------------------------------------------------------------------- 665 666void SimGroup::addObject( SimObject* obj ) 667{ 668 _addObject( obj ); 669} 670 671//----------------------------------------------------------------------------- 672 673void SimGroup::removeObject( SimObject* obj ) 674{ 675 lock(); 676 _removeObjectNoLock( obj ); 677 unlock(); 678} 679 680//----------------------------------------------------------------------------- 681 682void SimGroup::_removeObjectNoLock( SimObject* obj ) 683{ 684 if( obj->mGroup == this ) 685 { 686 obj->onGroupRemove(); 687 688 mNameDictionary.remove( obj ); 689 mObjectList.remove( obj ); 690 obj->mGroup = 0; 691 692 getSetModificationSignal().trigger( SetObjectRemoved, this, obj ); 693 if( obj->isProperlyAdded() ) 694 onObjectRemoved_callback( obj ); 695 obj->decRefCount(); 696 } 697} 698 699//----------------------------------------------------------------------------- 700 701void SimGroup::pushObject( SimObject* object ) 702{ 703 _addObject( object, true ); 704} 705 706//----------------------------------------------------------------------------- 707 708void SimGroup::popObject() 709{ 710 MutexHandle handle; 711 handle.lock( mMutex ); 712 713 if(mObjectList.empty() ) 714 { 715 AssertWarn( false, "SimGroup::popObject - Stack underflow" ); 716 return; 717 } 718 719 SimObject* object = mObjectList.last(); 720 mObjectList.pop_back(); 721 722 object->onGroupRemove(); 723 object->mGroup = NULL; 724 725 clearNotify( object ); 726 mNameDictionary.remove( object ); 727 728 getSetModificationSignal().trigger( SetObjectAdded, this, object ); 729 if( object->isProperlyAdded() ) 730 onObjectRemoved_callback( object ); 731 732 object->decRefCount(); 733} 734 735//----------------------------------------------------------------------------- 736 737void SimGroup::onRemove() 738{ 739 lock(); 740 if( !mObjectList.empty() ) 741 { 742 mObjectList.sortId(); 743 clear(); 744 } 745 SimObject::onRemove(); 746 unlock(); 747} 748 749//----------------------------------------------------------------------------- 750 751void SimGroup::clear() 752{ 753 lock(); 754 while( size() > 0 ) 755 { 756 SimObject* object = mObjectList.last(); 757 object->onGroupRemove(); 758 759 mObjectList.pop_back(); 760 mNameDictionary.remove( object ); 761 object->mGroup = 0; 762 763 getSetModificationSignal().trigger( SetObjectRemoved, this, object ); 764 if( object->isProperlyAdded() ) 765 onObjectRemoved_callback( object ); 766 767 if( engineAPI::gUseConsoleInterop ) 768 object->deleteObject(); 769 else 770 object->decRefCount(); 771 } 772 unlock(); 773 774 getSetModificationSignal().trigger( SetCleared, this, NULL ); 775} 776 777//----------------------------------------------------------------------------- 778 779SimObject *SimGroup::findObject(const char *namePath) 780{ 781 // find the end of the object name 782 S32 len; 783 for(len = 0; namePath[len] != 0 && namePath[len] != '/'; len++) 784 ; 785 786 StringTableEntry stName = StringTable->lookupn(namePath, len); 787 if(!stName) 788 return NULL; 789 790 SimObject *root = mNameDictionary.find( stName ); 791 if( !root ) 792 return NULL; 793 794 if(namePath[len] == 0) 795 return root; 796 797 return root->findObject(namePath + len + 1); 798} 799 800//----------------------------------------------------------------------------- 801 802SimGroup* SimGroup::clone() 803{ 804 // Skip SimSet::clone since we do not want to steal the child objects 805 // from this group. 806 807 SimObject* object = SimObject::clone(); 808 SimGroup* group = dynamic_cast< SimGroup* >( object ); 809 if( !group ) 810 { 811 object->deleteObject(); 812 return NULL; 813 } 814 815 return group; 816} 817 818//----------------------------------------------------------------------------- 819 820SimGroup* SimGroup::deepClone() 821{ 822 // Clone the group object. 823 824 SimObject* object = Parent::deepClone(); 825 SimGroup* group = dynamic_cast< SimGroup* >( object ); 826 if( !group ) 827 { 828 object->deleteObject(); 829 return NULL; 830 } 831 832 // Clone all child objects. 833 834 for( iterator iter = begin(); iter != end(); ++ iter ) 835 group->addObject( ( *iter )->deepClone() ); 836 837 return group; 838} 839 840//----------------------------------------------------------------------------- 841 842bool SimGroup::processArguments(S32, ConsoleValueRef *argv) 843{ 844 return true; 845} 846 847 848SimObject* SimGroup::getObject(const S32& index) 849{ 850 if (index < 0 || index >= size()) 851 { 852 Con::errorf("Set::getObject - index out of range."); 853 return NULL; 854 } 855 856 return (*this)[index]; 857} 858//----------------------------------------------------------------------------- 859 860SimObject* SimGroupIterator::operator++() 861{ 862 SimGroup* set; 863 if ((set = dynamic_cast<SimGroup*>(*stack.last().itr)) != 0) 864 { 865 if (!set->empty()) 866 { 867 stack.push_back(set); 868 return *stack.last().itr; 869 } 870 } 871 872 while (++stack.last().itr == stack.last().set->end()) 873 { 874 stack.pop_back(); 875 if (stack.empty()) 876 return 0; 877 } 878 return *stack.last().itr; 879} 880 881//============================================================================= 882// API. 883//============================================================================= 884// MARK: ---- API ---- 885 886//----------------------------------------------------------------------------- 887 888DefineEngineMethod( SimSet, listObjects, void, (),, 889 "Dump a list of all objects contained in the set to the console." ) 890{ 891 object->lock(); 892 SimSet::iterator itr; 893 for(itr = object->begin(); itr != object->end(); itr++) 894 { 895 SimObject *obj = *itr; 896 bool isSet = dynamic_cast<SimSet *>(obj) != 0; 897 const char *name = obj->getName(); 898 if(name) 899 Con::printf(" %d,\"%s\": %s %s", obj->getId(), name, 900 obj->getClassName(), isSet ? "(g)":""); 901 else 902 Con::printf(" %d: %s %s", obj->getId(), obj->getClassName(), 903 isSet ? "(g)" : ""); 904 } 905 object->unlock(); 906} 907 908//----------------------------------------------------------------------------- 909 910DefineEngineStringlyVariadicMethod( SimSet, add, void, 3, 0, 911 "( SimObject objects... ) Add the given objects to the set.\n" 912 "@param objects The objects to add to the set." ) 913{ 914 for(S32 i = 2; i < argc; i++) 915 { 916 SimObject *obj = Sim::findObject( argv[ i ] ); 917 if(obj) 918 object->addObject( obj ); 919 else 920 Con::printf("Set::add: Object \"%s\" doesn't exist", (const char*)argv[ i ] ); 921 } 922} 923 924//----------------------------------------------------------------------------- 925 926DefineEngineStringlyVariadicMethod( SimSet, remove, void, 3, 0, 927 "( SimObject objects... ) Remove the given objects from the set.\n" 928 "@param objects The objects to remove from the set." ) 929{ 930 for(S32 i = 2; i < argc; i++) 931 { 932 SimObject *obj = Sim::findObject(argv[i]); 933 object->lock(); 934 if(obj && object->find(object->begin(),object->end(),obj) != object->end()) 935 object->removeObject(obj); 936 else 937 Con::printf("Set::remove: Object \"%s\" does not exist in set", (const char*)argv[i]); 938 object->unlock(); 939 } 940} 941 942//----------------------------------------------------------------------------- 943 944DefineEngineMethod( SimSet, clear, void, (),, 945 "Remove all objects from the set." ) 946{ 947 object->clear(); 948} 949 950//----------------------------------------------------------------------------- 951 952//UNSAFE; don't want this in the new API 953DefineEngineMethod( SimSet, deleteAllObjects, void, (), , "() Delete all objects in the set." ) 954{ 955 object->deleteAllObjects(); 956} 957 958//----------------------------------------------------------------------------- 959 960DefineEngineMethod( SimSet, getRandom, SimObject*, (),, 961 "Return a random object from the set.\n" 962 "@return A randomly selected object from the set or -1 if the set is empty." ) 963{ 964 return object->getRandom(); 965} 966 967//----------------------------------------------------------------------------- 968 969DefineEngineStringlyVariadicMethod( SimSet, callOnChildren, void, 3, 0, 970 "( string method, string args... ) Call a method on all objects contained in the set.\n\n" 971 "@param method The name of the method to call.\n" 972 "@param args The arguments to the method.\n\n" 973 "@note This method recurses into all SimSets that are children to the set.\n\n" 974 "@see callOnChildrenNoRecurse" ) 975{ 976 object->callOnChildren( (const char*)argv[2], argc - 3, argv + 3 ); 977} 978 979//----------------------------------------------------------------------------- 980 981DefineEngineStringlyVariadicMethod( SimSet, callOnChildrenNoRecurse, void, 3, 0, 982 "( string method, string args... ) Call a method on all objects contained in the set.\n\n" 983 "@param method The name of the method to call.\n" 984 "@param args The arguments to the method.\n\n" 985 "@note This method does not recurse into child SimSets.\n\n" 986 "@see callOnChildren" ) 987{ 988 object->callOnChildren( (const char*)argv[2], argc - 3, argv + 3, false ); 989} 990 991//----------------------------------------------------------------------------- 992 993DefineEngineMethod( SimSet, reorderChild, void, ( SimObject* child1, SimObject* child2 ),, 994 "Make sure child1 is ordered right before child2 in the set.\n" 995 "@param child1 The first child. The object must already be contained in the set.\n" 996 "@param child2 The second child. The object must already be contained in the set." ) 997{ 998 SimObject* pObject = child1; 999 SimObject* pTarget = child2; 1000 1001 if(pObject && pTarget) 1002 { 1003 object->reOrder(pObject,pTarget); 1004 } 1005} 1006 1007//----------------------------------------------------------------------------- 1008 1009DefineEngineMethod( SimSet, getCount, S32, (),, 1010 "Get the number of objects contained in the set.\n" 1011 "@return The number of objects contained in the set." ) 1012{ 1013 return object->size(); 1014} 1015 1016//----------------------------------------------------------------------------- 1017 1018DEFINE_CALLIN( fnSimSet_getCountRecursive, getCountRecursive, SimSet, U32, ( SimSet* set ),,, 1019 "Get the number of direct and indirect child objects contained in the set.\n" 1020 "@return The number of objects contained in the set as well as in other sets contained directly or indirectly in the set." ) 1021{ 1022 return set->sizeRecursive(); 1023} 1024 1025DefineEngineMethod( SimSet, getFullCount, S32, (), , "() Get the number of direct and indirect child objects contained in the set.\n" 1026 "@return The number of objects contained in the set as well as in other sets contained directly or indirectly in the set." ) 1027{ 1028 return object->sizeRecursive(); 1029} 1030 1031//----------------------------------------------------------------------------- 1032 1033DefineEngineMethod( SimSet, getObject, SimObject*, ( U32 index ),, 1034 "Get the object at the given index.\n" 1035 "@param index The object index.\n" 1036 "@return The object at the given index or -1 if index is out of range." ) 1037{ 1038 if( index < 0 || index >= object->size() ) 1039 { 1040 Con::errorf( "Set::getObject - index out of range." ); 1041 return NULL; 1042 } 1043 1044 return ( *object )[ index ]; 1045} 1046 1047//----------------------------------------------------------------------------- 1048 1049DefineEngineMethod( SimSet, getObjectIndex, S32, ( SimObject* obj ),, 1050 "Return the index of the given object in this set.\n" 1051 "@param obj The object for which to return the index. Must be contained in the set.\n" 1052 "@return The index of the object or -1 if the object is not contained in the set." ) 1053{ 1054 if( !obj ) 1055 return -1; 1056 1057 object->lock(); 1058 S32 count = 0; 1059 for( SimSet::iterator i = object->begin(); i != object->end(); i++) 1060 { 1061 if( *i == obj ) 1062 { 1063 object->unlock(); 1064 return count; 1065 } 1066 1067 ++count; 1068 } 1069 object->unlock(); 1070 1071 return -1; 1072} 1073 1074//----------------------------------------------------------------------------- 1075 1076DefineEngineMethod( SimSet, isMember, bool, ( SimObject* obj ),, 1077 "Test whether the given object belongs to the set.\n" 1078 "@param obj The object.\n" 1079 "@return True if the object is contained in the set; false otherwise." ) 1080{ 1081 if( !obj ) 1082 return false; 1083 1084 return ( object->find( object->begin(), object->end(), obj ) != object->end() ); 1085} 1086 1087//----------------------------------------------------------------------------- 1088 1089DefineEngineMethod( SimSet, findObjectByInternalName, SimObject*, ( const char* internalName, bool searchChildren ), ( false ), 1090 "Find an object in the set by its internal name.\n" 1091 "@param internalName The internal name of the object to look for.\n" 1092 "@param searchChildren If true, SimSets contained in the set will be recursively searched for the object.\n" 1093 "@return The object with the given internal name or 0 if no match was found.\n" ) 1094{ 1095 StringTableEntry pcName = StringTable->insert( internalName ); 1096 return object->findObjectByInternalName( pcName, searchChildren ); 1097} 1098 1099//----------------------------------------------------------------------------- 1100 1101DefineEngineMethod( SimSet, bringToFront, void, ( SimObject* obj ),, 1102 "Make the given object the first object in the set.\n" 1103 "@param obj The object to bring to the frontmost position. Must be contained in the set." ) 1104{ 1105 if( obj ) 1106 object->bringObjectToFront( obj ); 1107} 1108 1109//----------------------------------------------------------------------------- 1110 1111DefineEngineMethod( SimSet, pushToBack, void, ( SimObject* obj ),, 1112 "Make the given object the last object in the set.\n" 1113 "@param obj The object to bring to the last position. Must be contained in the set." ) 1114{ 1115 if( obj ) 1116 object->pushObjectToBack( obj ); 1117} 1118 1119//----------------------------------------------------------------------------- 1120 1121DefineEngineMethod( SimSet, sort, void, ( const char * callbackFunction ), , "( string callbackFunction ) Sort the objects in the set using the given comparison function.\n" 1122 "@param callbackFunction Name of a function that takes two object arguments A and B and returns -1 if A is less, 1 if B is less, and 0 if both are equal." ) 1123{ 1124 object->scriptSort( callbackFunction ); 1125} 1126 1127//----------------------------------------------------------------------------- 1128 1129DefineEngineMethod( SimSet, acceptsAsChild, bool, ( SimObject* obj ),, 1130 "Test whether the given object may be added to the set.\n" 1131 "@param obj The object to test for potential membership.\n" 1132 "@return True if the object may be added to the set, false otherwise." ) 1133{ 1134 if( !obj ) 1135 return false; 1136 1137 return object->acceptsAsChild( obj ); 1138} 1139