Advertisement
agmike

Using TrackSearch

Aug 22nd, 2014
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.82 KB | None | 0 0
  1. BEFORE
  2. final class RFHumpRouteScanner
  3. {
  4.     public RFHumpController Owner;
  5.     public float MaxSearchDistance = 5000.0f;
  6.     public bool Overflow = false;
  7.     public int BadJunctionId = -1;
  8.  
  9.     public RFHumpRoute Scan();
  10.  
  11.    
  12.     // ****************************************************
  13.     //
  14.     //    I M P L E M E N T A T I O N
  15.     //
  16.     // ****************************************************
  17.  
  18.     int ops = 0;
  19.     int hops = 0;
  20.     float distance = 0.0f;
  21.    
  22.     // final void L(string l) { Interface.Log(l); }
  23.     // final string LN(MapObject o) { return "'" + o.GetLocalisedName() + "' (" + o.GetId()+")"; }
  24.     // final string CN(MapObject o) { return o.GetGSClassName() + ", asset: "+o.GetAsset().GetKUID().GetLogString(); }
  25.  
  26.     final void IncOps() { if (++ops >= 10000) { ops = 0; Owner.Sleep(0.01f); } }
  27.     final bool IncHops() { Overflow = Overflow or ++hops > 50; return !Overflow; }
  28.     final void DecHops() { --hops; }
  29.  
  30.     final int GetJunctionDirectionToObject(Junction jnc, Trackside origin)
  31.     {
  32.         int[] directions = new int[4];
  33.         int dirCount = 0;
  34.         directions[dirCount++] = Junction.DIRECTION_BACKWARD;
  35.         directions[dirCount++] = Junction.DIRECTION_LEFT;
  36.         directions[dirCount++] = Junction.DIRECTION_RIGHT;
  37.         directions[dirCount++] = Junction.DIRECTION_FORWARD;
  38.         int originDirection = Junction.DIRECTION_NONE;
  39.         Trackside[] firstInDirection = new Trackside[dirCount];
  40.         bool ambiguity = false;
  41.         float searchRestartDistance = 5000.0f;
  42.         int i;
  43.         for(i = 0; i < dirCount; i++) {
  44.             float totalDistance = 0.0f;
  45.             GSTrackSearch gs = jnc.BeginTrackSearch(directions[i]);
  46.             if (!gs) continue;
  47.             while (gs.SearchNextObject()) {
  48.                 Trackside found = cast <Trackside> gs.GetObject();
  49.                 if (!found) continue;
  50.                 int j;
  51.                 for (j = 0; j < dirCount; ++j)
  52.                     ambiguity = ambiguity or firstInDirection[j] == found;
  53.                 if (!firstInDirection[i])
  54.                     firstInDirection[i] = found;
  55.                 if(found == origin) {
  56.                     ambiguity = ambiguity or originDirection != Junction.DIRECTION_NONE;
  57.                     originDirection = directions[i];
  58.                     break;
  59.                 }
  60.                 float distance = totalDistance + gs.GetDistance();
  61.                 if (distance > MaxSearchDistance or found.isclass(Junction) or ambiguity)
  62.                     break;
  63.                 if(distance >= searchRestartDistance) {
  64.                     totalDistance = distance;
  65.                     gs = found.BeginTrackSearch(gs.GetFacingRelativeToSearchDirection());
  66.                 }
  67.                 IncOps();
  68.             }
  69.         }
  70.         if (ambiguity)
  71.             return Junction.DIRECTION_NONE;
  72.         return originDirection;
  73.     }
  74.  
  75.     RFHumpRoute Scan(GSTrackSearch it, Trackside origin)
  76.     {
  77.         if (!IncHops())
  78.             return null;
  79.         RFHumpRoute ret = null;
  80.         Trackside prev = origin, found;
  81.         while (it.SearchNextObject()) {
  82.             if (!(found = cast <Trackside> it.GetObject()))
  83.                 continue;
  84.             RFHumpMarker marker;
  85.             Junction junc;
  86.             if ((marker = cast <RFHumpMarker> found) and marker.HumpTrack >= 0) {
  87.                 if (marker.HumpTrack > 0) {
  88.                     ret = new RFHumpRoute();
  89.                     ret.TrackNumber = marker.HumpTrack;
  90.                     ret.MarkerId = marker.GetId();
  91.                 }
  92.                 break;
  93.             }
  94.             else if (junc = cast <Junction> found) {
  95.                 int dir = GetJunctionDirectionToObject(junc, prev);
  96.                 if  (dir == Junction.DIRECTION_BACKWARD) {
  97.                     ret = new RFHumpRoute();
  98.                     ret.JnId = junc.GetId();
  99.                     ret.Left = Scan(junc.BeginTrackSearch(Junction.DIRECTION_LEFT), junc);
  100.                     ret.Right = Scan(junc.BeginTrackSearch(Junction.DIRECTION_RIGHT), junc);
  101.                 }
  102.                 else if (dir == Junction.DIRECTION_LEFT) {
  103.                     ret = new RFHumpRoute();
  104.                     ret.JnId = junc.GetId();
  105.                     ret.Left = Scan(junc.BeginTrackSearch(Junction.DIRECTION_BACKWARD), junc);
  106.                 }
  107.                 else if (dir == Junction.DIRECTION_RIGHT) {
  108.                     ret = new RFHumpRoute();
  109.                     ret.JnId = junc.GetId();
  110.                     ret.Right = Scan(junc.BeginTrackSearch(Junction.DIRECTION_BACKWARD), junc);
  111.                 }
  112.                 else {
  113.                     BadJunctionId = junc.GetId();
  114.                 }
  115.                 break;
  116.             }
  117.             if (it.GetDistance() > MaxSearchDistance)
  118.                 break;
  119.             prev = found;
  120.             IncOps();
  121.         }
  122.         DecHops();
  123.         return ret;
  124.     }
  125.  
  126.     public RFHumpRoute Scan()
  127.     {
  128.         Overflow = false;
  129.         BadJunctionId = -1;
  130.         return Scan(Owner.BeginTrackSearch(true), Owner);
  131.     }
  132. };
  133.  
  134. AFTER
  135. final class RFHumpJuncDirSearch isclass RFHumpTrackSearchObserver
  136. {
  137.     public Junction Jn;
  138.     public int Dir;
  139.     public Trackside Origin;
  140.     public Trackside[] FirstObjects;
  141.    
  142.     public Trackside First = null;
  143.     public bool OriginFound = false;
  144.     public bool FirstConflict = false;
  145.    
  146.     public GSTrackSearch Begin() { return Jn.BeginTrackSearch(Dir); }
  147.    
  148.     public bool Next(RFHumpTrackSearchCursor cursor)
  149.     {
  150.         Trackside obj = cast <Trackside> cursor.GetObject();
  151.         if (obj) {
  152.             if (!First)
  153.                 First = obj;
  154.             OriginFound = obj == Origin;
  155.             int i, count = FirstObjects.size();
  156.             for (i = 0; i < count; ++i)
  157.                 if (FirstObjects[i] == obj)
  158.                     FirstConflict = true;
  159.         }
  160.         return !OriginFound and !FirstConflict;
  161.     }
  162. };
  163.  
  164. public int GetJunctionDirectionToObject(Junction jnc, Trackside origin)
  165. {
  166.     int[] directions = new int[4];
  167.     int dirCount = 0;
  168.     directions[dirCount++] = Junction.DIRECTION_BACKWARD;
  169.     directions[dirCount++] = Junction.DIRECTION_LEFT;
  170.     directions[dirCount++] = Junction.DIRECTION_RIGHT;
  171.     directions[dirCount++] = Junction.DIRECTION_FORWARD;
  172.     int originDirection = Junction.DIRECTION_NONE;
  173.     Trackside[] firstInDirection = new Trackside[dirCount];
  174.     bool ambiguity = false;
  175.     int i;
  176.     for(i = 0; i < dirCount; i++) {
  177.         RFHumpJuncDirSearch s = new RFHumpJuncDirSearch();
  178.         s.Jn = jnc;
  179.         s.Dir = directions[i];
  180.         s.Origin = origin;
  181.         s.FirstObjects = firstInDirection;
  182.         RFHumpTrackSearch.Begin(s, 0, 0, 0);
  183.        
  184.         if (s.FirstConflict or s.OriginFound and originDirection != Junction.DIRECTION_NONE)
  185.             return Junction.DIRECTION_NONE;
  186.         if(s.OriginFound)
  187.             originDirection = directions[i];
  188.         firstInDirection[i] = s.First;
  189.     }
  190.     return originDirection;
  191. }
  192.  
  193. final class RFHumpRoutesSearch isclass RFHumpTrackSearchObserver
  194. {
  195.     public GSTrackSearch Search;
  196.     public int Dir;
  197.     public Trackside Origin;
  198.     public int Hops = 0;
  199.     public int MaxHops = 20;
  200.    
  201.     public RFHumpRoute Root = null;
  202.     public bool Overflow = false;
  203.     public int BadJunctionId = 0;
  204.    
  205.     public Trackside Prev;
  206.    
  207.     public bool IsOk() { return !Overflow and !BadJunctionId; }
  208.    
  209.     public RFHumpRoute Scan(GSTrackSearch it, Trackside origin)
  210.     {
  211.         if (!IsOk())
  212.             return null;
  213.         RFHumpRoutesSearch s = new RFHumpRoutesSearch();
  214.         s.Search = it;
  215.         s.Origin = origin;
  216.         s.Hops = Hops + 1;
  217.         s.MaxHops = MaxHops;
  218.         RFHumpTrackSearch.Begin(s, 1000000, 0, 0);
  219.         if (s.Overflow) Overflow = s.Overflow;
  220.         if (s.BadJunctionId) BadJunctionId = s.BadJunctionId;
  221.         return s.Root;
  222.     }
  223.    
  224.     public GSTrackSearch Begin()
  225.     {
  226.         Prev = Origin;
  227.         if (Hops < MaxHops)
  228.             return Search;
  229.         Overflow = true;
  230.         return null;
  231.     }
  232.    
  233.     public bool Next(RFHumpTrackSearchCursor cursor)
  234.     {
  235.         Trackside current = cast <Trackside> cursor.GetObject();
  236.         if (current) {
  237.             RFHumpMarker marker = cast <RFHumpMarker> current;
  238.             Junction junc = cast <Junction> current;
  239.             if (marker and marker.HumpTrack >= 0) {
  240.                 if (marker.HumpTrack > 0) {
  241.                     Root = new RFHumpRoute();
  242.                     Root.TrackNumber = marker.HumpTrack;
  243.                     Root.MarkerId = marker.GetId();
  244.                 }
  245.                 return false;
  246.             }
  247.             else if (junc) {
  248.                 int dir = RFHumpUtils.GetJunctionDirectionToObject(junc, Prev);
  249.                 if  (dir == Junction.DIRECTION_BACKWARD) {
  250.                     Root = new RFHumpRoute();
  251.                     Root.JnId = junc.GetId();
  252.                     Root.Left = Scan(junc.BeginTrackSearch(Junction.DIRECTION_LEFT), junc);
  253.                     Root.Right = Scan(junc.BeginTrackSearch(Junction.DIRECTION_RIGHT), junc);
  254.                 }
  255.                 else if (dir == Junction.DIRECTION_LEFT) {
  256.                     Root = new RFHumpRoute();
  257.                     Root.JnId = junc.GetId();
  258.                     Root.Left = Scan(junc.BeginTrackSearch(Junction.DIRECTION_BACKWARD), junc);
  259.                 }
  260.                 else if (dir == Junction.DIRECTION_RIGHT) {
  261.                     Root = new RFHumpRoute();
  262.                     Root.JnId = junc.GetId();
  263.                     Root.Right = Scan(junc.BeginTrackSearch(Junction.DIRECTION_BACKWARD), junc);
  264.                 }
  265.                 else
  266.                     BadJunctionId = junc.GetId();
  267.                 return false;
  268.             }
  269.             Prev = current;
  270.         }
  271.         return IsOk();
  272.     }
  273. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement