<commit_before>﻿using SME;
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;

namespace SME.Tracer
{
	public abstract class Tracer : IDisposable
	{
		protected SignalEntry[] m_props;
		private bool m_first = true;

		public static IEnumerable<SignalEntry> BuildPropertyMap()
		{
			return
				(from bus in BusManager.Busses.Union(BusManager.ClockedBusses.Select(x => x.Key)).Union(BusManager.InternalBusses).Distinct()
				 from prop in bus.BusType.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public)
				 let isDriver = bus.BusType.CustomAttributes.Any(x => typeof(TopLevelInputBusAttribute).IsAssignableFrom(x.AttributeType))
				 let isInternal = BusManager.InternalBusses.Contains(bus)
				 select new SignalEntry()
				 {
					 Bus = bus,
					 Property = prop,
					 IsDriver = isDriver,
					 IsInternal = isInternal,
					 SortKey = 
						(bus.BusType.DeclaringType != null ? bus.BusType.DeclaringType.Name + "." : string.Empty)
						+ bus.BusType.Name + "." + prop.Name
				})
				.Where(x => !x.IsInternal)
				.OrderByDescending(x => x.IsDriver)
				.ThenBy(x => x.SortKey)
			 ;
		}


		protected abstract void OutputSignalNames(SignalEntry[] signals);
		protected abstract void OuputSignalData(IEnumerable<Tuple<SignalEntry, object>> values);

		protected virtual IEnumerable<Tuple<SignalEntry, object>> GetValues()
		{
			foreach (var p in m_props)
			{
				object value = null;

				try
				{
					value = p.Property.GetValue(p.Bus);
				}
				catch (Exception ex)
				{
					if (ex is System.Reflection.TargetInvocationException)
						ex = ((System.Reflection.TargetInvocationException)ex).InnerException;

					Console.WriteLine(string.Format("Failed to read item {0}.{1}, message: {2}", p.Property.DeclaringType.FullName, p.Property.Name, ex));
					value = ex;
				}

				yield return new Tuple<SignalEntry, object>(p, value);
			}
		}

		public void OnClockTick()<commit_msg>Fixed not reporting read violations from the tracer<commit_after>﻿using SME;
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;

namespace SME.Tracer
{
	public abstract class Tracer : IDisposable
	{
		protected SignalEntry[] m_props;
		private bool m_first = true;

		public static IEnumerable<SignalEntry> BuildPropertyMap()
		{
			return
				(from bus in BusManager.Busses.Union(BusManager.ClockedBusses.Select(x => x.Key)).Union(BusManager.InternalBusses).Distinct()
				 from prop in bus.BusType.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public)
				 let isDriver = bus.BusType.CustomAttributes.Any(x => typeof(TopLevelInputBusAttribute).IsAssignableFrom(x.AttributeType))
				 let isInternal = BusManager.InternalBusses.Contains(bus)
				 select new SignalEntry()
				 {
					 Bus = bus,
					 Property = prop,
					 IsDriver = isDriver,
					 IsInternal = isInternal,
					 SortKey = 
						(bus.BusType.DeclaringType != null ? bus.BusType.DeclaringType.Name + "." : string.Empty)
						+ bus.BusType.Name + "." + prop.Name
				})
				.Where(x => !x.IsInternal)
				.OrderByDescending(x => x.IsDriver)
				.ThenBy(x => x.SortKey)
			 ;
		}


		protected abstract void OutputSignalNames(SignalEntry[] signals);
		protected abstract void OuputSignalData(IEnumerable<Tuple<SignalEntry, object>> values);

		protected virtual IEnumerable<Tuple<SignalEntry, object>> GetValues()
		{
			foreach (var p in m_props)
			{
				object value = null;

				try
				{
					value = p.Property.GetValue(p.Bus);
				}
				catch (Exception ex)
				{
					if (ex is System.Reflection.TargetInvocationException)
						ex = ((System.Reflection.TargetInvocationException)ex).InnerException;

					if (!(ex is SME.ReadViolationException))
						Console.WriteLine(string.Format("Failed to read item {0}.{1}, message: {2}", p.Property.DeclaringType.FullName, p.Property.Name, ex));
					value = ex;
				}

				yield return new Tuple<SignalEntry, object>(p, value);
			}
		}

		public void OnClockTick()
{'fraction_non_alphanumeric': 0.1128280598479274, 'fraction_numerical': 0.0014716703458425313, 'mean_word_length': 3.6712485681557845, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '205935', 'n_tokens_mistral': 1529, 'n_tokens_neox': 1220, 'n_words': 270}