// The thread! private void ProcessingThread(object index) { // Get function pointers VPO_GetError GetError = (VPO_GetError)Marshal.GetDelegateForFunctionPointer(GetProcAddress(dlls[(int)index], "VPO_GetError"), typeof(VPO_GetError)); VPO_LoadWAD LoadWAD = (VPO_LoadWAD)Marshal.GetDelegateForFunctionPointer(GetProcAddress(dlls[(int)index], "VPO_LoadWAD"), typeof(VPO_LoadWAD)); VPO_OpenMap OpenMap = (VPO_OpenMap)Marshal.GetDelegateForFunctionPointer(GetProcAddress(dlls[(int)index], "VPO_OpenMap"), typeof(VPO_OpenMap)); VPO_FreeWAD FreeWAD = (VPO_FreeWAD)Marshal.GetDelegateForFunctionPointer(GetProcAddress(dlls[(int)index], "VPO_FreeWAD"), typeof(VPO_FreeWAD)); VPO_CloseMap CloseMap = (VPO_CloseMap)Marshal.GetDelegateForFunctionPointer(GetProcAddress(dlls[(int)index], "VPO_CloseMap"), typeof(VPO_CloseMap)); VPO_TestSpot TestSpot = (VPO_TestSpot)Marshal.GetDelegateForFunctionPointer(GetProcAddress(dlls[(int)index], "VPO_TestSpot"), typeof(VPO_TestSpot)); try { // Load the map if (LoadWAD(filename) != 0) { throw new Exception("VPO is unable to read this file."); } if (OpenMap(mapname) != 0) { throw new Exception("VPO is unable to open this map."); } // Processing Queue <TilePoint> todo = new Queue <TilePoint>(POINTS_PER_ITERATION); Queue <PointData> done = new Queue <PointData>(POINTS_PER_ITERATION); while (true) { lock (points) { // Flush done points to the results int numdone = done.Count; for (int i = 0; i < numdone; i++) { results.Enqueue(done.Dequeue()); } // Get points from the waiting queue into my todo queue for processing int numtodo = Math.Min(POINTS_PER_ITERATION, points.Count); for (int i = 0; i < numtodo; i++) { todo.Enqueue(points.Dequeue()); } } // Don't keep locking! if (todo.Count == 0) { Thread.Sleep(31); } // Process the points while (todo.Count > 0) { TilePoint p = todo.Dequeue(); PointData pd = new PointData(); pd.point = p; for (int i = 0; i < TEST_ANGLES.Length; i++) { pd.result = (PointResult)TestSpot(p.x, p.y, TEST_HEIGHT, TEST_ANGLES[i], ref pd.visplanes, ref pd.drawsegs, ref pd.openings, ref pd.solidsegs); } done.Enqueue(pd); } } } catch (ThreadInterruptedException) { } finally { CloseMap(); FreeWAD(); } }
// The thread! private void ProcessingThread() { IntPtr context = VPO_NewContext(); // Load the map bool isHexen = General.Map.HEXEN; if (VPO_LoadWAD(context, filename) != 0) { throw new Exception("VPO is unable to read this file."); } if (VPO_OpenMap(context, mapname, ref isHexen) != 0) { throw new Exception("VPO is unable to open this map."); } VPO_OpenDoorSectors(context, BuilderPlug.InterfaceForm.OpenDoors ? 1 : -1); //mxd // Processing Queue <TilePoint> todo = new Queue <TilePoint>(POINTS_PER_ITERATION); Queue <PointData> done = new Queue <PointData>(POINTS_PER_ITERATION); while (true) { lock (points) { // Wait for work if (points.Count == 0 && !stopflag) { Monitor.Wait(points); } // Flush done points to the results int numdone = done.Count; for (int i = 0; i < numdone; i++) { results.Enqueue(done.Dequeue()); } if (stopflag) { break; } // Get points from the waiting queue into my todo queue for processing int numtodo = Math.Min(POINTS_PER_ITERATION, points.Count); for (int i = 0; i < numtodo; i++) { todo.Enqueue(points.Dequeue()); } } // Process the points while (todo.Count > 0) { TilePoint p = todo.Dequeue(); PointData pd = new PointData(); pd.point = p; for (int i = 0; i < TEST_ANGLES.Length; i++) { pd.result = (PointResult)VPO_TestSpot(context, p.x, p.y, TEST_HEIGHT, TEST_ANGLES[i], ref pd.visplanes, ref pd.drawsegs, ref pd.openings, ref pd.solidsegs); } done.Enqueue(pd); } } VPO_CloseMap(context); VPO_FreeWAD(context); VPO_DeleteContext(context); }