This repository has been archived on 2023-02-02. You can view files and clone it, but cannot push or open issues or pull requests.
mfgames-nitride-cil/src/MfGames.Nitride/Contents
2023-01-15 12:43:42 -06:00
..
ByteArrayBinaryContent.cs refactor: renaming namespaces 2022-09-06 00:53:22 -05:00
EntityBinaryContentExtensions.cs refactor: renaming namespaces 2022-09-06 00:53:22 -05:00
EntityContentExtensions.cs refactor: renaming namespaces 2022-09-06 00:53:22 -05:00
EntityTextContentExtensions.cs refactor!: renamed GetText to GetTextContentString 2023-01-15 12:43:42 -06:00
FileBinaryContent.cs refactor!: fixed missed namespaces 2023-01-14 18:19:42 -06:00
FileTextContent.cs refactor!: fixed missed namespaces 2023-01-14 18:19:42 -06:00
IBinaryContent.cs refactor: renaming namespaces 2022-09-06 00:53:22 -05:00
IBinaryContentConvertable.cs refactor: renaming namespaces 2022-09-06 00:53:22 -05:00
IContent.cs refactor: renaming namespaces 2022-09-06 00:53:22 -05:00
ITextContent.cs refactor: renaming namespaces 2022-09-06 00:53:22 -05:00
ITextContentConvertable.cs refactor: renaming namespaces 2022-09-06 00:53:22 -05:00
README.md feat!: renaming files and projects 2022-09-06 00:40:00 -05:00
StringTextContent.cs refactor: renaming namespaces 2022-09-06 00:53:22 -05:00
TextContentExtensions.cs refactor!: renamed GetText to GetTextContentString 2023-01-15 12:43:42 -06:00

Contents

The contents of a file may be stored as a component, however this increases the memory pressure when Nitride works with hundreds or thousands of files. To reduce this, memory is loaded on demand through an abstracted components such as IBinaryContent and ITextContent.

Exclusivity

The content interfaces are treated as mutually exclusive with each other by extending the IContent interface. The intended reason for this is to have a single source of data that doesn't go out of sync. Adding or setting a IBinaryContent will remove the other content components in the entity, even ones that are defined in other classes. In effect, all IContent will be removed to ensure that. This is implemented via a number of extension operations.

Entity entity;
IBinaryContent binaryContent;
ITextContent textContent;

entity.Add(binaryContent);
Assert.Equal(1, entity.Count);
Assert.True(entity.Has<IBinaryContent>());
Assert.True(entity.HasBinaryContent());
Assert.True(entity.HasContent());

entity.SetContent(textContent);
Assert.Equal(1, entity.Count);
Assert.False(entity.Has<IBinaryContent>());
Assert.False(entity.HasBinaryContent());
Assert.True(entity.Has<ITextContent>());
Assert.True(entity.HasTextContent());
Assert.True(entity.HasContent());

entity.RemoveContent();
Assert.Equal(0, entity.Count);
Assert.False(entity.Has<IBinaryContent>());
Assert.False(entity.HasBinaryContent());
Assert.False(entity.Has<ITextContent>());
Assert.False(entity.HasTextContent());
Assert.False(entity.HasContent());

This exclusivity can be ignored by using direct Add<>, Set<>, and Remove<> methods on the entity. That would allow multiple content to be added and removed at the same time.

Entity entity;
IBinaryContent binaryContent = entity.Get<IBinaryContent>();
using Stream binaryStream = binaryContent.GetStream();
using StreamReader binaryReader = new StreamReader(binaryStream);
var text = binaryReader.ReadToEnd();
var textContent = new StringTextContent(text);

var switchedEntity = entity
    .Set<ITextContent>(textContent)
    .Remove<IBinaryContent>();
Assert.Equal(1, switchedEntity.Count);
Assert.True(switchedEntity.Has<ITextContent>());
Assert.False(switchedEntity.Has<ITextContent>());

var mergedEntity = entity
    .Set<ITextContent>(textContent);
Assert.Equal(2, switchedEntity.Count);
Assert.True(switchedEntity.Has<ITextContent>());
Assert.True(switchedEntity.Has<ITextContent>());

Implementing this with a parent interface (IContent) allows future content providers, such as IXmlContent or other future content sources.

IBinaryComponent

Most files start as only having access to binary content.

Entity entity;
IBinaryContent content = entity.Get<IBinaryContent>();
using Stream stream = content.GetStream();

There is no guarantee that the data behind the stream is loaded into memory or even available on disk. Instead, the stream is good until it goes out of scope.

IBinaryContentConvertable

There is an additional interface that allows a content to be converted into an IBinaryContent).

FileTextContent textContent;
IBinaryContent binaryContent = textContent.ToBinaryContent();

Extension Methods

There are some convenience methods for working with entity components and content since they are frequently used.

IBinaryContent content = entity.GetBinaryContent();
bool has = entity.HasBinaryContent();

// Internally, this uses `SetContent` above with some additonal type safety.
entity = entity.SetBinaryContent(content);

ByteArrayBinaryComponent

The ByteArrayBinaryComponent is a component that contains the entire binary data in memory and returns it via System.IO.MemoryStream objects.

byte[] bytes;
var content = new ByteArrayBinaryComponent(bytes);

FileBinaryContent

The TextBinaryContent takes a path or FileInfo object as the parameter and will produce a stream directly from the file without loading the file into memory.

FileInfo file;

new FileBinaryContent(@"C:\Temp\Bob.txt");
new FileBinaryContent(file);

ITextContent

Text content allows for retrieving the contents via TextReader instead of a stream.

ITextContent content;

using TextReader reader = content.GetReader();

ITextContentConvertable

There is an additional interface that allows a content to be converted into an ITextContent).

FileBinaryContent binaryContent;
ITextContent textContent =  binaryContent.ToTextContent();

Extension Methods

Like the binary, there are some convenience methods for working with entity components.

ITextContent content = entity.GetTextContent();
bool has = entity.HasTextContent();

entity = entity.SetTextContent(content);

StringTextContent

A simple, in-memory string text content takes a string as the parameter.

string input;
ITextContent content = new StringTextContent(input);

FileTextContent

The TextFileContent takes a path or FileInfo object as the parameter and will produce a reader directly from the file without loading the file into memory.

FileInfo file;

new FileTextContent(@"C:\Temp\Bob.txt");
new FileTextContent(file);