public void Update(CameraDirectionMovementTracker lastcamera, Matrix4 resmat, float _zn, bool names, bool discs, Color namecolour) // FOREGROUND no thread { _starnamesbusy = true; // from update to Transfertoforeground we are busy if (_starnamesforeground.Count >= maxstarscached) // if we have too many, clean up, to free memory { List <LinkedListNode <StarNames> > removelist = new List <LinkedListNode <StarNames> >(); LinkedListNode <StarNames> pos = _starnamesforeground.First; while (pos != null) { StarNames sys = pos.Value; if (!sys.inview) // if not painting { removelist.Add(pos); } pos = pos.Next; } //Tools.LogToFile(String.Format("starnameupd Remove {0}", removelist.Count )); //Console.WriteLine("Remove {0}", removelist.Count); foreach (LinkedListNode <StarNames> rpos in removelist) { StarNames sys = rpos.Value; sys.Dispose(); _starnamesforeground.Remove(rpos); _starnamesbackground.Remove(sys.pos); } } _lastcamera = lastcamera; _resmat = resmat; _znear = _zn; _nameson = names; _discson = discs; _namecolour = namecolour; nsThread = new System.Threading.Thread(NamedStars) { Name = "Calculate Named Stars", IsBackground = true }; nsThread.Start(); }
private void NamedStars() // background thread.. run after Update. Thread never deletes, only adds to its own structures { try // just in case someone tears us down.. { int lylimit = (int)(_starlimitly / _lastcamera.LastZoom); lylimit = Math.Max(lylimit, 1); int sqlylimit = lylimit * lylimit; // in squared distance limit from viewpoint StarGrid.TransFormInfo ti = new StarGrid.TransFormInfo(_resmat, _znear, _glControl.Width, _glControl.Height, sqlylimit, _lastcamera.LastCameraPos); SortedDictionary <float, StarGrid.InViewInfo> inviewlist = new SortedDictionary <float, StarGrid.InViewInfo>(new DuplicateKeyComparer <float>()); // who's in view, sorted by distance //Stopwatch sw1 = new Stopwatch();sw1.Start(); Tools.LogToFile(String.Format("starnamesest Estimate at {0} len {1}", ti.campos, sqlylimit)); _stargrids.GetSystemsInView(ref inviewlist, 2000.0F, ti); // consider all grids under 2k from current pos. //Tools.LogToFile(String.Format("starnamesest Took {0} in view {1}", sw1.ElapsedMilliseconds, inviewlist.Count)); float textscalingw = Math.Min(_starnamemaxly, Math.Max(_starnamesizely / _lastcamera.LastZoom, _starnameminly)); // per char float starsize = Math.Min(Math.Max(_lastcamera.LastZoom / 10F, 1.0F), 20F); // Normal stars are at 1F. //Console.WriteLine("Per char {0} h {1} sc {2} ", textscalingw, textscalingh, starsize); foreach (StarNames s in _starnamesbackground.Values) // all items not processed { s.updatedinview = false; // only items remaining will clear this } _needrepaint = false; // assume nothing changes int painted = 0; //string res = ""; // used to view whats added/removed/draw.. foreach (StarGrid.InViewInfo inview in inviewlist.Values) // for all in viewport, sorted by distance from camera position { using (SQLiteConnectionSystem cn = new SQLiteConnectionSystem()) { StarNames sys = null; bool draw = false; if (_starnamesbackground.ContainsKey(inview.position)) // if already there.. { sys = _starnamesbackground[inview.position]; sys.updatedinview = true; draw = (_discson && sys.paintstar == null && sys.newstar == null) || (_nameson && ((sys.nametexture == null && sys.newnametexture == null))); painted++; } else if (painted < maxstars) { ISystem sc = _formmap.FindSystem(inview.position, cn); // with the open connection, find this star.. if (sc != null) // if can't be resolved, ignore { sys = new StarNames(sc, inview.position); // we keep position in here using same floats as inview so it will match _starnamesbackground.Add(inview.position, sys); // add to our database _starnamestoforeground.Add(sys); // send to foreground for adding draw = true; painted++; //Tools.LogToFile(String.Format("starnamesest: push {0}", sys.Pos)); //res += "N"; } } else { break; // no point doing any more.. got our fill of items } if (draw) { _needrepaint = true; // changed a item.. needs a repaint if (_nameson) { float width = textscalingw * sys.name.Length; Bitmap map = DatasetBuilder.DrawString(sys.name, _namecolour, _starfont); sys.newnametexture = TexturedQuadData.FromBitmap(map, new PointData(sys.pos.X, sys.pos.Y, sys.pos.Z), _lastcamera.Rotation, width, textscalingw * 4.0F, _startextoffset + width / 2, 0); sys.rotation = _lastcamera.Rotation; // remember when we were when we draw it sys.zoom = _lastcamera.LastZoom; } if (_discson) { sys.newstar = new PointData(sys.pos.X, sys.pos.Y, sys.pos.Z, starsize, inview.AsColor); } } } } foreach (StarNames s in _starnamesbackground.Values) // only items above will remain. { //if (s.inview != s.updatedinview) res += (s.updatedinview) ? "+" : "-"; _needrepaint = _needrepaint || (s.inview != s.updatedinview); // set if we change our mind on any of the items s.inview = s.updatedinview; // copy flag over, causes foreground to start removing them } //if ( _needrepaint) Console.WriteLine(String.Format("starnamesest in view {0} limit {1} repaint {2} {3}", inviewlist.Count, lylimit, _needrepaint, res)); //Tools.LogToFile(String.Format("starnamesest added all delta {0} topaint {1}", sw1.ElapsedMilliseconds, painted)); } catch (Exception ex) { System.Diagnostics.Trace.WriteLine("Exception watcher: " + ex.Message); System.Diagnostics.Trace.WriteLine("Trace: " + ex.StackTrace); } _formmap.BeginInvoke((System.Windows.Forms.MethodInvoker) delegate // kick the UI thread to process. { _formmap.ChangeNamedStars(); }); }