Game Development Community

Gui object namespace issue

by Richard Ranft · in Torque 2D Beginner · 02/11/2014 (11:35 am) · 10 replies

Someone please give this a shot and tell me how it goes:

Create a gui control that is named and is assigned a class -
<GuiControl
  Name="MyControl"
  class="MyClass"
  ... />

What I'm finding is that for some reason the system is failing to correctly handle this anymore. I'm getting this (slightly modified) error:
// modified the Assert to give me the object name - the message was frustratingly vague.
Fatal: (c:\egmtools\assettools\engine\source\console\consolenamespace.cc @ 165) Namespace::unlinkClass - reference count to ToyCategorySelectList is less than 0

About the author

I was a soldier, then a computer technician, an electrician, a technical writer, game programmer, and now software test/tools developer. I've been a hobbyist programmer since the age of 13.


#1
02/11/2014 (12:55 pm)
Haven't tested your code but I got this error whenever I tried to assign a Name to a SkeletonObject(in my Spine branch).

%obj.setName("test");

->throws an error upon toy reload/restart/quit

No errors without that.
#2
02/11/2014 (1:39 pm)
Is that object assigned a script class? I'm thinking something has broken in the namespace linking system in all of the clean up. I'm slowly working through file comparisons now to see if I can track it down.
#3
02/11/2014 (7:49 pm)
Hack fix: mRefCountToParent >= 0. Others have found different solutions.
#4
02/11/2014 (10:06 pm)
Guess it works in the short term - I'll keep looking though. This needs to work correctly. When I get it straightened out I'll drop a pull request.

Thanks!
#5
02/13/2014 (9:34 am)
Ok, Master branch has this:
bool Namespace::unlinkClass(Namespace *parent)
{
   Namespace *walk = this;
   while(walk->mParent && walk->mParent->mName == mName)
      walk = walk->mParent;

   if(walk->mParent && walk->mParent != parent)
   {
      Con::errorf(ConsoleLogEntry::General, "Namespace::unlinkClass - cannot unlink namespace parent linkage for %s for %s.",
         walk->mName, walk->mParent->mName);
      return false;
   }

   mRefCountToParent--;
   AssertFatal(mRefCountToParent >= 0, "Namespace::unlinkClass - reference count to parent is less than 0");

   if(mRefCountToParent == 0)
      walk->mParent = NULL;

   trashCache();

   return true;
}

Development branch has this:
bool Namespace::unlinkClass(Namespace *parent)
{
   Namespace *walk = this;
   while(walk->mParent && walk->mParent->mName == mName)
      walk = walk->mParent;

   if(walk->mParent && walk->mParent != parent)
   {
      Con::errorf(ConsoleLogEntry::General, "Namespace::unlinkClass - cannot unlink namespace parent linkage for %s for %s.",
         walk->mName, walk->mParent->mName);
      return false;
   }

   AssertFatal(mRefCountToParent > 0, "Namespace::unlinkClass - reference count to parent is less than 0");
   mRefCountToParent--;

   if(mRefCountToParent == 0)
      walk->mParent = NULL;

   trashCache();

   return true;
}

Master is generally in line with what T3D does, though the particulars are different. Was there a reason for this particular change? Is there something we're trying to gain that warrants the additional research that is necessary to make this work correctly?

What's really funny is that they look like they do the same thing. <shrug>
#6
02/13/2014 (9:57 am)
Here's the background on this change:

github.com/GarageGames/Torque2D/pull/126
#7
02/13/2014 (10:10 am)
<edit>
I take it back - that fix is already applied (commented not removed) and this assert still gets triggered in Development, whereas the Master version continues to be stable. I guess I'll dig a little more....
#8
02/13/2014 (6:00 pm)
Looks like the problem is the taml parser. It's calling setClassNamespace and setSuperClassNamespace, which assume that the object has already been added.

Think this works
void SimObject::setClassNamespace( const char *classNamespace )
{
   mClassName = StringTable->insert( classNamespace );
   if (mFlags.test(Added))
       linkNamespaces();
}

void SimObject::setSuperClassNamespace( const char *superClassNamespace )
{  
   mSuperClassName = StringTable->insert( superClassNamespace );
    if (mFlags.test(Added))
        linkNamespaces();
}
#9
02/13/2014 (8:24 pm)
Very nice! Thanks tons - hadn't gotten that far yet.
#10
02/23/2014 (6:19 pm)
Sent in a pull request for this.