//
// Copyright (c) 2019-2021 Ryujinx
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see .
//
using Ryujinx.Audio.Renderer.Utils;
using Ryujinx.Common;
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace Ryujinx.Audio.Renderer.Common
{
///
/// Represents a adjacent matrix.
///
/// This is used for splitter routing.
public class EdgeMatrix
{
///
/// Backing used for node connections.
///
private BitArray _storage;
///
/// The count of nodes of the current instance.
///
private int _nodeCount;
///
/// Get the required work buffer size memory needed for the .
///
/// The count of nodes.
/// The size required for the given .
public static int GetWorkBufferSize(int nodeCount)
{
int size = BitUtils.AlignUp(nodeCount * nodeCount, Constants.BufferAlignment);
return size / Unsafe.SizeOf();
}
///
/// Initializes the instance with backing memory.
///
/// The backing memory.
/// The count of nodes.
public void Initialize(Memory edgeMatrixWorkBuffer, int nodeCount)
{
Debug.Assert(edgeMatrixWorkBuffer.Length >= GetWorkBufferSize(nodeCount));
_storage = new BitArray(edgeMatrixWorkBuffer);
_nodeCount = nodeCount;
_storage.Reset();
}
///
/// Test if the bit at the given index is set.
///
/// A bit index.
/// Returns true if the bit at the given index is set
public bool Test(int index)
{
return _storage.Test(index);
}
///
/// Reset all bits in the storage.
///
public void Reset()
{
_storage.Reset();
}
///
/// Reset the bit at the given index.
///
/// A bit index.
public void Reset(int index)
{
_storage.Reset(index);
}
///
/// Set the bit at the given index.
///
/// A bit index.
public void Set(int index)
{
_storage.Set(index);
}
///
/// Connect a given source to a given destination.
///
/// The source index.
/// The destination index.
public void Connect(int source, int destination)
{
Debug.Assert(source < _nodeCount);
Debug.Assert(destination < _nodeCount);
_storage.Set(_nodeCount * source + destination);
}
///
/// Check if the given source is connected to the given destination.
///
/// The source index.
/// The destination index.
/// Returns true if the given source is connected to the given destination.
public bool Connected(int source, int destination)
{
Debug.Assert(source < _nodeCount);
Debug.Assert(destination < _nodeCount);
return _storage.Test(_nodeCount * source + destination);
}
///
/// Disconnect a given source from a given destination.
///
/// The source index.
/// The destination index.
public void Disconnect(int source, int destination)
{
Debug.Assert(source < _nodeCount);
Debug.Assert(destination < _nodeCount);
_storage.Reset(_nodeCount * source + destination);
}
///
/// Remove all edges from a given source.
///
/// The source index.
public void RemoveEdges(int source)
{
for (int i = 0; i < _nodeCount; i++)
{
Disconnect(source, i);
}
}
///
/// Get the total node count.
///
/// The total node count.
public int GetNodeCount()
{
return _nodeCount;
}
}
}