Beispiel #1
0
        public DeviceState(IReadOnlyDictionary <string, RwCallback> callbacks = null, Action <string> debugLogCallback = null)
        {
            int size = (Unsafe.SizeOf <TState>() + RegisterSize - 1) / RegisterSize;

            _readableRegisters = new BitArray(size);
            _writableRegisters = new BitArray(size);

            _readCallbacks  = new Dictionary <int, Func <int> >();
            _writeCallbacks = new Dictionary <int, Action <int> >();

            if (debugLogCallback != null)
            {
                _fieldNamesForDebug = new Dictionary <int, string>();
                _debugLogCallback   = debugLogCallback;
            }

            var fields = typeof(TState).GetFields();
            int offset = 0;

            for (int fieldIndex = 0; fieldIndex < fields.Length; fieldIndex++)
            {
                var field   = fields[fieldIndex];
                var regAttr = field.GetCustomAttributes <RegisterAttribute>(false).FirstOrDefault();

                int sizeOfField = SizeCalculator.SizeOf(field.FieldType);

                for (int i = 0; i < ((sizeOfField + 3) & ~3); i += 4)
                {
                    _readableRegisters[(offset + i) / RegisterSize] = regAttr?.AccessControl.HasFlag(AccessControl.ReadOnly) ?? true;
                    _writableRegisters[(offset + i) / RegisterSize] = regAttr?.AccessControl.HasFlag(AccessControl.WriteOnly) ?? true;
                }

                if (callbacks != null && callbacks.TryGetValue(field.Name, out var cb))
                {
                    if (cb.Read != null)
                    {
                        _readCallbacks.Add(offset, cb.Read);
                    }

                    if (cb.Write != null)
                    {
                        _writeCallbacks.Add(offset, cb.Write);
                    }
                }

                if (debugLogCallback != null)
                {
                    _fieldNamesForDebug.Add(offset, field.Name);
                }

                offset += sizeOfField;
            }

            Debug.Assert(offset == Unsafe.SizeOf <TState>());
        }
Beispiel #2
0
        public DeviceState(IReadOnlyDictionary <string, RwCallback> callbacks = null, Action <string> debugLogCallback = null)
        {
            _readCallbacks  = new Func <int> [Size];
            _writeCallbacks = new Action <int> [Size];

            if (debugLogCallback != null)
            {
                _fieldNamesForDebug = new Dictionary <uint, string>();
                _debugLogCallback   = debugLogCallback;
            }

            var fields = typeof(TState).GetFields();
            int offset = 0;

            for (int fieldIndex = 0; fieldIndex < fields.Length; fieldIndex++)
            {
                var field = fields[fieldIndex];

                int sizeOfField = SizeCalculator.SizeOf(field.FieldType);

                for (int i = 0; i < ((sizeOfField + 3) & ~3); i += 4)
                {
                    int index = (offset + i) / RegisterSize;

                    if (callbacks != null && callbacks.TryGetValue(field.Name, out var cb))
                    {
                        if (cb.Read != null)
                        {
                            _readCallbacks[index] = cb.Read;
                        }

                        if (cb.Write != null)
                        {
                            _writeCallbacks[index] = cb.Write;
                        }
                    }
                }

                if (debugLogCallback != null)
                {
                    _fieldNamesForDebug.Add((uint)offset, field.Name);
                }

                offset += sizeOfField;
            }

            Debug.Assert(offset == Unsafe.SizeOf <TState>());
        }