All Projects → grofit → persistity

grofit / persistity

Licence: MIT license
A persistence framework for game developers

Programming Languages

C#
18002 projects
Batchfile
5799 projects

Projects that are alternatives of or similar to persistity

Binary
Generic and fast binary serializer for Go
Stars: ✭ 86 (+152.94%)
Mutual labels:  serialization, binary
surge
Simple, specialised, and efficient binary marshaling
Stars: ✭ 36 (+5.88%)
Mutual labels:  serialization, binary
Borer
Efficient CBOR and JSON (de)serialization in Scala
Stars: ✭ 131 (+285.29%)
Mutual labels:  serialization, binary
Pbf
A low-level, lightweight protocol buffers implementation in JavaScript.
Stars: ✭ 618 (+1717.65%)
Mutual labels:  serialization, binary
Apex.Serialization
High performance contract-less binary serializer for .NET
Stars: ✭ 82 (+141.18%)
Mutual labels:  serialization, binary
Beeschema
Binary Schema Library for C#
Stars: ✭ 46 (+35.29%)
Mutual labels:  serialization, binary
Chronicle Wire
A Java Serialisation Library that supports multiple formats
Stars: ✭ 204 (+500%)
Mutual labels:  serialization, binary
Fspickler
A fast multi-format message serializer for .NET
Stars: ✭ 299 (+779.41%)
Mutual labels:  serialization, binary
nason
🗜 Ultra tiny serializer / encoder with plugin-support. Useful to build binary files containing images, strings, numbers and more!
Stars: ✭ 30 (-11.76%)
Mutual labels:  serialization, binary
parco
🏇🏻 generalist, fast and tiny binary parser and compiler generator, powered by Go 1.18+ Generics
Stars: ✭ 57 (+67.65%)
Mutual labels:  serialization, binary
Iguana
universal serialization engine
Stars: ✭ 481 (+1314.71%)
Mutual labels:  serialization, binary
Bois
Salar.Bois is a compact, fast and powerful binary serializer for .NET Framework. With Bois you can serialize your existing objects with almost no change.
Stars: ✭ 53 (+55.88%)
Mutual labels:  serialization, binary
Fastbinaryencoding
Fast Binary Encoding is ultra fast and universal serialization solution for C++, C#, Go, Java, JavaScript, Kotlin, Python, Ruby, Swift
Stars: ✭ 421 (+1138.24%)
Mutual labels:  serialization, binary
Bincode
A binary encoder / decoder implementation in Rust.
Stars: ✭ 1,100 (+3135.29%)
Mutual labels:  serialization, binary
Ceras
Universal binary serializer for a wide variety of scenarios https://discord.gg/FGaCX4c
Stars: ✭ 374 (+1000%)
Mutual labels:  serialization, binary
Binaryserializer
A declarative serialization framework for controlling formatting of data at the byte and bit level using field bindings, converters, and code.
Stars: ✭ 197 (+479.41%)
Mutual labels:  serialization, binary
sia
Sia - Binary serialisation and deserialisation
Stars: ✭ 52 (+52.94%)
Mutual labels:  serialization, binary
binary
package binary is a lightweight and high-performance serialization library to encode/decode between go data and []byte.
Stars: ✭ 20 (-41.18%)
Mutual labels:  serialization, binary
GenericProtocol
⚡️ A fast TCP event based buffered server/client protocol for transferring data over the (inter)net in .NET 🌐
Stars: ✭ 38 (+11.76%)
Mutual labels:  serialization, binary
GroBuf
Fast binary serializer
Stars: ✭ 56 (+64.71%)
Mutual labels:  serialization, binary

Persistity

A pipeline based data persistence framework (a bit like ETL) for game developers for use with Unity, Monogame or other .net based engines/frameworks.

Build Status Nuget Version Join Discord Chat

What is it?

Its an async pipeline for handling complex extract/transform/load interactions for your models in any format (xml/json/binary out the box).

At its heart it has:

  • Transformers (Transforms one statically typed model to another)
  • Serializers (Extracts and serializes models)
  • Processors (Does stuff on the data before it reaches its destination)
  • Endpoints (Sends or Recieves data from an end point)

These are basically steps in a workflow or pipeline, so you can chain together steps to do stuff like converting your model to json, url encoding it and then sending it to a web service, or converting it to binary and then pumping it into a file.

Example

Here are a few examples covering incoming and outgoing data pipelines.

Setting Up Models For persistence

[Persist]
public class SomeClass
{
    [PersistData]
    public float SomeValue { get; set; }
}

The [Persist] attribute indicates this is a root class for persisting, and [PersistData] indicates that the property should be mapped. In nested classes or collections you can omit the [Persist] attribute, its just the root type that needs this.

Outgoing Pipeline

So for example lets cover a quick use case for saving your game state data to a binary file:

// This would normally be setup once in your app or via DI etc
var mappingRegistry = new MappingRegistry(new DefaultTypeMapper());
var binarySerializer = new BinarySerializer(mappingRegistry);
var fileEndpoint = new FileEndpoint("savegame.sav");

// Create the pipeline which wraps the underlying steps
var saveToBinaryFilePipeline = new PipelineBuilder()
    .StartWithInput()
    .SerializeWith(binarySerializer)
    .ThenSendTo(fileEndpoint)
    .Build();

// Execute the pipeline with your game data
await saveToBinaryFilePipeline.Execute(myGameData);

Now lets imagine we decide we wanted to encrypt our game data before we spat it out, we would make changes like so:

// Same setup as before but we add an encryption processor
var encryptor = new AesEncryptor("some-pass-phrase");
var encryptionProcessor = new EncryptDataProcessor(encryptor);

// Same as before but we now add the processor into the mix
var saveToBinaryFilePipeline = new PipelineBuilder()
    .StartWithInput()
    .SerializeWith(binarySerializer)
    .ProcessWith(encryptionProcessor)
    .ThenSendTo(fileEndpoint)
    .Build();

// Execute the pipeline with your game data
await saveToBinaryFilePipeline.Execute(myGameData);

This then will encrypt your data after it has been transformed and will pass it over to be persisted in a file. You could easily decide to change from using a file to using PlayerPrefs by just changing the FileWriter to PlayerPrefWriter and using that .SendTo(playerPrefsEndpoint) which would send your data to player prefs rather than a flat file.

Incoming Pipeline

So in the previous example we covered sending data to the file system, but lets imagine we wanted that encrypted saved data back in at some point, we could do:

// This would normally be setup once in your app or via DI etc
var mappingRegistry = new MappingRegistry(new DefaultTypeMapper());
var binaryDeserializer = new BinaryDeserializer(mappingRegistry);
var encryptor = new AesEncryptor("some-pass-phrase");
var decryptionProcessor = new DecryptDataProcessor(encryptor);
var fileEndpoint = new FileEndpoint("savegame.sav");

// Create the pipeline which wraps the underlying steps
var loadBinaryFilePipeline = new PipelineBuilder()
    .StartFrom(fileEndpoint)
    .ProcessWith(decryptionProcessor)
    .DeserializeWith(binaryDeserializer)
    .Build();

// Execute the pipeline to get your game data
var myGameData = await loadBinaryFilePipeline.Execute<MyGameData>();

This will decrypt and convert your lovely binary data back into a statically typed object for you to do as you wish with.

Creating Pipelines Without Builder

So the builder offers a simple and flexible way to create pipelines wherever you want, however in most complex situations you may just want to create your own pipeline implementation and pass that around, which can be done for the above like so:

public class ABespokePipeline : IPipeline
{
    private ISerializer _serializer;
    private ITransformer _dataTransformer;
    private ISendDataEndpoint _endpoint;

    public SaveEncryptedBinaryFilePipeline(ISerializer serializer, IToEntityDatabaseDataTransformer dataTransformer, ISendDataEndpoint endpoint)
    {
        _serializer = serializer;
        _dataTransformer = dataTransformer;
        _endpoint = endpoint;
    }

    public Task<object> Execute(object input = null, object state = null)
    {
        var transformedData = _dataTransformer.Transform(input);
        var output = _serializer.Serialize(transformedData, true);
        return _endpoint.Send(output);
    }
}

Creating Strongly Typed Pipeline via Builder

public class MyStronglyTypedPipeline : BuiltPipeline
{
    protected override IEnumerable<IPipelineStep> BuildSteps()
    {
        return new PipelineBuilder()
            .StartFromInput()                
            // Build the pipeline
            .BuildSteps();
    }
}

Using The Framework

All you need to do is download the stable release and install the unity package.

Docs

There are a load of documents covering the various classes and how to use them within the docs folder.

Advised Setup

It is HIGHLY recommended you use some sort of DI system to setup your high level pipelines and just inject them in via IoC to your objects. This will make your setup and configuration far more sane.

For those using unity something like Zenject works wonders here.

Dependencies

  • LazyData (There are specific LazyData libs for each serialization format)

Historically LazyData used to be part of this project, but realistically it could be consumed outside of here without any problem, so it made sense to make it into its own library.

Docs

Check out the docs directory for docs which go into more detail.

More Waffle

The general idea here is that this framework provides a basis for you to add your own transformers, processors and endpoints. So you may be fine with the default transformers and processors out of the box, but you will probably want to add some of your own for your own workflows.

You can just use pieces of this as well if you want, like if you just want to use the serialization, just take that and use it without the transformers and the other endpoints etc.

It was originally started as a branch in the EcsRx repository but as it was not tied to that was brought out into its own repo.

The overall goal is to attempt to build simple building blocks for consumers to create larger workflows of data, such as scenarios like extracting data as JSON and posting to a web service, or extracting data as binary and putting into a flat file.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].