Processing added and deleted objects in my plugin

Hello! These are snippets of my model, view model and view, I am trying to keep track of all points that are currently in the rhino doc, my view model is in charge of adding objects to the model´s queues based on rhino add and delete object events, what I am not sure about is if this is a right approach, how to process the queues, do I use an async task? do I run another thread? do I trigger the queue processing by another event? I am very much new to csharp so I want to be careful about choosing next steps and Id like to get some advice from more experienced developers. The list of points is what I would like the viewmodel to watch and expose to my view but I am struggling to glue everything together. any advice is greatly appreciated, thank you

    public class MyPoint
    {
        public string Id { get; set; }

        public string X { get; set; }
        public string Y { get; set; }

        public string Z { get; set; }

    }
// Model
    internal class ObjPoints
    {
        List<MyPoint> points;
        public List<MyPoint> Points
        {
            get { return points; }
            set { points = value; }
        }


        Queue<RhinoObject> addedObjs;
        public Queue<RhinoObject> AddedObjs
        {
            get { return addedObjs; }
            set { addedObjs = value; }
        }

        Queue<RhinoObject> deletedObjs;
        public Queue<RhinoObject> DeletedObjs
        {
            get { return deletedObjs; }
            set { deletedObjs = value; }
        }

       
        public ObjPoints()
        {
            points = new List<MyPoint>();
            addedObjs = new Queue<RhinoObject>();
            deletedObjs = new Queue<RhinoObject>();
        }

        public HashSet<Point3d> ObjectToPoints(RhinoObject obj)
        {

            var geometry = obj.Geometry;
            List<Point3d> controlPoints = new List<Point3d>();
            HashSet<Point3d> resultSet = new HashSet<Point3d>();

            if (geometry is Brep brep)
            {
                foreach (var vertex in brep.Vertices)
                {
                    controlPoints.Add(vertex.Location);
                }
            }
            else if (geometry is Surface surface)
            {
                var nurbsSurface = surface.ToNurbsSurface();
                for (int i = 0; i < nurbsSurface.Points.CountU; i++)
                {
                    for (int j = 0; j < nurbsSurface.Points.CountV; j++)
                    {
                        controlPoints.Add(nurbsSurface.Points.GetControlPoint(i, j).Location);
                    }
                }
            }
            else if (geometry is Curve curve)
            {
                var nurbsCurve = curve.ToNurbsCurve();
                for (int i = 0; i < nurbsCurve.Points.Count; i++)
                {
                    controlPoints.Add(nurbsCurve.Points[i].Location);
                }
            }
            else if (geometry is Point point)
            {
                controlPoints.Add(point.Location);
            }

            if (controlPoints.Count > 0)
            {
                resultSet = new HashSet<Point3d>(controlPoints);
            }
            else
            {
                RhinoApp.WriteLine($"Failed to get control points of object {obj}");
            }
            return resultSet;
        }

      
    }
// View model
public class MainViewModel : BaseViewModel
{
    ObjPoints objPoints;

    ObservableCollection<MyPoint> _points;
    public IEnumerable<MyPoint> Points => _points;


    public MainViewModel()
    {
        RhinoApp.Idle += OnIdle;
        RhinoDoc.DeleteRhinoObject += OnDeleteRhinoObject;
        RhinoDoc.AddRhinoObject += OnAddRhinoObject;

        _points = new ObservableCollection<MyPoint>();
    }

    private void OnAddRhinoObject(object sender, RhinoObjectEventArgs e)
    {
        RhinoApp.WriteLine("Adding object");
        var obj = e.TheObject;
        objPoints.AddedObjs.Enqueue(obj);
    }

    private void OnDeleteRhinoObject(object sender, RhinoObjectEventArgs e)
    {
        RhinoApp.WriteLine("Deleting objects");
        var obj = e.TheObject;
        objPoints.DeletedObjs.Enqueue(obj);
    }

    private void OnIdle(object sender, EventArgs e)
    {
        //RhinoApp.WriteLine("Rhino Idling");

    }


}

// grid whose data should be bound to my view model
var grid = new GridView { ShowHeader = true, DataStore = v_model.Points};

CommonViewFuncs.AddGridColumn<MyPoint>(grid, "Point_ID", (p => p.Id));

CommonViewFuncs.AddGridColumn<MyPoint>(grid, "Coord_X", (p => p.X));

CommonViewFuncs.AddGridColumn<MyPoint>(grid, "Coord_Y", (p => p.Y));

CommonViewFuncs.AddGridColumn<MyPoint>(grid, "Coord_Z", (p => p.Z));

internal static void AddGridColumn<TItem>(GridView grid, string headerText, Expression<Func<TItem, string>> propertySelector)
{
    var col = new GridColumn
    {
        HeaderText = headerText,
        DataCell = new TextBoxCell { Binding = Binding.Property(propertySelector) },
        AutoSize = true,
        Editable = false
    };
    grid.Columns.Add(col);
}

Hi @Vojta_Hanzlík,

When you detect an event you need to process, set a flag, or in your case add to some kind of event queue, an then hook up a RhinoApp.Idle event handler.

The RhinoApp.Idle handler is called unhook the event handler and process your queues.

– Dale

Hi @Vojta_Hanzlík,

Something to look at …

PointsViewModel.cs (10.1 KB)

– Dale