LavishNav .Net problem

MstrGareth

Active Member
I am trying to reach Lax on this, but was wondering if anyone else has seen this problem and maybe figured out a hack for it.

The problem is the BestContainer.FQN sometimes returns corrupted data (frequently actually)

Output:
get_BestRegionID, FQN by BestContainerXYZ lookup: BlindingShallows
get_BestRegionID, FQN by BestContainerXYZ lookup: Ø)ÓdingShallows
get_BestRegionID, FQN by BestContainerXYZ lookup: BlindingShallows
get_BestRegionID, FQN by BestContainerXYZ lookup: BlindingShallows
get_BestRegionID, FQN by BestContainerXYZ lookup: BlindingShallows


Code:
        public bool BestRegionTest
        {
            get
            {
                string BRSafeString;
                try
                {

                        BRSafeString = Navigator.Tree.FindRegion(CurrentChunkName).BestContainer(X, Y, Z).FQN;
                        DebugOut("get_BestRegionID, FQN by BestContainerXYZ lookup: " + BRSafeString);
                        return true;
                }
                catch (Exception ez)
                {
                    DebugOut("BestRegionTest: " + ez.Message);
                    return false;
                }
            }
        }
 

MstrGareth

Active Member
More samples

Region.FQN in both FindRegion and BestContainer

--------------------
get_BestRegionID, FQN by BestContainerXYZ lookup: KonarthiPoin
get_BestRegionID, FQN by FindRegion lookup: KonarthiPoint
--------------------
get_BestRegionID, FQN by BestContainerXYZ lookup: KonarthiPoin
get_BestRegionID, FQN by FindRegion lookup: KonarthiPoint
--------------------
get_BestRegionID, FQN by BestContainerXYZ lookup: XªrthiPoin
get_BestRegionID, FQN by BestContainerXYZ lookup: KonarthiPoin
get_BestRegionID, FQN by FindRegion lookup: KonarthiPoint
--------------------
get_BestRegionID, FQN by BestContainerXYZ lookup: KonarthiPoin
get_BestRegionID, FQN by FindRegion lookup: KonarthiPoint
--------------------
get_BestRegionID, FQN by BestContainerXYZ lookup: KonarthiPoin
get_BestRegionID, FQN by FindRegion lookup: XªrthiPoint
--------------------
get_BestRegionID, FQN by BestContainerXYZ lookup: KonarthiPoin
get_BestRegionID, FQN by FindRegion lookup: KonarthiPoint
--------------------
get_BestRegionID, FQN by BestContainerXYZ lookup: XªrthiPoin
get_BestRegionID, FQN by BestContainerXYZ lookup: KonarthiPoin
get_BestRegionID, FQN by FindRegion lookup: KonarthiPoint
--------------------
get_BestRegionID, FQN by BestContainerXYZ lookup: XªrthiPoin
get_BestRegionID, FQN by BestContainerXYZ lookup: KonarthiPoin
get_BestRegionID, FQN by FindRegion lookup: KonarthiPoint
--------------------
get_BestRegionID, FQN by BestContainerXYZ lookup: KonarthiPoin
get_BestRegionID, FQN by FindRegion lookup: XªrthiPoint



Code:
        public bool BestRegionTest
        {
            get
            {
                string BRSafeString;
                string BRSafeString2;
                try
                {
                    DebugOut("--------------------");
                    do
                    {
                        BRSafeString = BaseRegion.BestContainer(X, Y, Z).FQN;
                        DebugOut("get_BestRegionID, FQN by BestContainerXYZ lookup: " + BRSafeString);
                        BRSafeString2 = BaseRegion.FindRegion(BRSafeString).FQN;
                    } while (BRSafeString2 == null);

                    DebugOut("get_BestRegionID, FQN by FindRegion lookup: " + BRSafeString2);
                    return true;
                }
                catch (Exception ez)
                {
                    DebugOut("Exception BestRegionTest: " + ez.Message);
                    return false;
                }
            }
        }
 

MstrGareth

Active Member
Working hack, slow but does the trick

Code:
        string BRSafeString;
        string BRSafeString2;
        public string BestRegion
        {
            get
            {
                
                try
                {

                    do
                    {
                        BRSafeString = BaseRegion.BestContainer(X, Y, Z).FQN;
                        BRSafeString2 = BaseRegion.FindRegion(BRSafeString).FQN;
                    } while (BRSafeString2 == null);

                    if (BaseRegion.FindRegion(BRSafeString).Type.Equals("Point"))
                    {

                        do
                        {
                            BRSafeString = BaseRegion.FindRegion(BRSafeString).Parent.FQN;
                            BRSafeString2 = BaseRegion.FindRegion(BRSafeString).FQN;
                        } while (BRSafeString2 == null);
                        DebugOut("get_BestRegionID, FQN after POINT check " + BRSafeString);
                    }
                    

                    return BRSafeString;
                }
                catch (Exception ez)
                {
                    DebugOut("Exception BestRegion: " + ez.Message);
                    return "";
                }
            }
        }
 

Lax

LavishSoft/InnerSpace Guru
I remember it being reported with EQ2 as well.

Tell me, what happens when you change it to this:

Code:
        public bool BestRegionTest
        {
            get
            {
                string BRSafeString;
                try
                {
[color=red]using(new FrameLock(true))
{[/color]
                        BRSafeString = Navigator.Tree.FindRegion(CurrentChunkName).BestContainer(X, Y, Z).FQN;
[color=red]}[/color]
                        DebugOut("get_BestRegionID, FQN by BestContainerXYZ lookup: " + BRSafeString);
                        return true;
                }
                catch (Exception ez)
                {
                    DebugOut("BestRegionTest: " + ez.Message);
                    return false;
                }
            }
        }
I don't have any information on the rest of the code to know if you'd ONLY be calling that function from within frame lock, but if you're not, then I would assume the function would complete in, oh, 5 frames..

My guess is that it's not frame locked at all, which I could see there being a race condition in GetMember<T> in that case, and the temporarily allocated memory storing that string can actually be freed and potentially storing other data before it is fully converted, which you are seeing. This puts me in a bind because obviously you and Blazer are expecting implicit frame locking to prevent that issue, but I am expecting .NET developers to use responsible frame locking so that I don't need to add another layer of implicit frame locking, which is significantly less efficient. But I've never been able to get anyone to actually use frame locking to their own advantage anyway so I guess I need to add the additional layer.
 

Lax

LavishSoft/InnerSpace Guru
Inner Space build 4612 is now up as a development build.

Changes:
1.09 Build 4612
- .NET 2.0
- Most LavishScriptAPI functions that enforce explicit frame locking when requested
(LavishScript.RequireExplicitFrameLock=true) now frame lock themselves when explicit frame locking
is not enforced.
This means if you switch to 4612 the race condition is eliminated and you should no longer see this behavior even if you are not explicitly frame locking. However, you SHOULD still be frame locking on your own, and I would suggest setting LavishScriptAPI.LavishScript.RequireExplicitFrameLock=true to identify potential problem areas, which will throw LavishVMAPI.Exceptions.NotLockedException() on most LavishScript API calls unless you are calling it from within frame lock.


Now... beyond that...
CurrentChunkName? FQNs? Why are we doing this? You should be keeping a reference to the region provided by Navigator.Tree.FindRegion(CurrentChunkName) solely to avoid having to make 3 separate managed=>unmanaged calls into LavishScript, which each individually will lock the frame, each time you want to access the region defined by the "current chunk". LavishNav regions are persistent objects, so you can hold onto them as long as you like. The only time you need to execute FindRegion(CurrentChunkName) is when CurrentChunkName changes. Even using the ID instead of the name would be an improvement, because LavishNav can look it up without performing a search.
 
Top Bottom