Discussion in 'Scripts (.NET)' started by MstrGareth, Aug 29, 2007.

  1. MstrGareth

    MstrGareth Active Member

    Messages:
    88
    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 (Text):
            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;
                    }
                }
            }
  2. Blazer

    Blazer Active Member

    Messages:
    47
    I have noticed this as well, but with eq2. I have not figured out a workaround either.
  3. MstrGareth

    MstrGareth Active Member

    Messages:
    88
    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 (Text):
            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;
                    }
                }
            }
  4. MstrGareth

    MstrGareth Active Member

    Messages:
    88
    Working hack, slow but does the trick

    Code (Text):
            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 "";
                    }
                }
            }
  5. Lax

    Lax LavishSoft/InnerSpace Guru

    Messages:
    18
    I remember it being reported with EQ2 as well.

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

    Code (Text):
            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.
  6. Lax

    Lax LavishSoft/InnerSpace Guru

    Messages:
    18
    Inner Space build 4612 is now up as a development build.

    Changes:
    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.

Share This Page