GithubHelp home page GithubHelp logo

ly774508966 / bakingsheet Goto Github PK

View Code? Open in Web Editor NEW

This project forked from cathei/bakingsheet

0.0 0.0 0.0 1.26 MB

Easy datasheet management for C# and Unity

License: MIT License

C# 100.00%

bakingsheet's Introduction

Nuget GitHub release (latest by date) GitHub

BakingSheet

Easy datasheet management for C# and Unity

Install

Download with NuGet or download .unitypackage release

Concept

Concept

BakingSheet's core concept is controlling datasheet schema from C# code, make things flexible while supporting multiple sources like .xlsx or Google sheets. Also, it helps to avoid having source datasheet files or parsing libraries for production applications. BakingSheet supports JSON serialization by default.

First Step

BakingSheet manages datasheet schema as C# code. Sheet class represents a table and SheetRow class represents a record. Below is example content of file Items.xlsx.

Id Name Price
ITEM_LVUP001 Warrior's Shield 10000
ITEM_LVUP002 Mage's Staff 10000
ITEM_LVUP003 Assassin's Dagger 10000
ITEM_POTION001 Health Potion 30
ITEM_POTION002 Mana Potion 50

Code below is corresponding BakingSheet class.

public class ItemSheet : Sheet<ItemSheet.Row>
{
    public class Row : SheetRow
    {
        // use name of matching column
        public string Name { get; private set; }
        public int Price { get; private set; }
    }
}

Note that Id column is already defined in base SheetRow class.

To represent collection of sheets, implement SheetContainerBase class.

public class SheetContainer : SheetContainerBase
{
    public SheetContainer(Microsoft.Extensions.Logging.ILogger logger) : base(logger) {}

    // use name of each matching sheet name from source
    public ItemSheet Items { get; private set; }
}

Importers

Importers are simple implementation extracts records from datasheet sources. These come as separated library, as it's user's decision to select datasheet source. User can have converting process, to convert datasheet to serialized files ahead of time and not include importers in production applications.

BakingSheet supports three basic importers

  • BakingSheet.Importers.Excel
  • BakingSheet.Importers.Google
  • BakingSheet.Importers.Csv

Below code shows how to convert .xlsx files from Excel/Files/Path directory.

// pass logger to receive logs
var sheetContainer = new SheetContainer(logger);

// create excel importer from path
var excelImporter = new ExcelSheetImporter("Excel/Files/Path");

// bake sheets from excel importer
await sheetContainer.Bake(excelImporter);

Save and Load Converted Datasheet

Below code shows how to save and load serialized json.

// save as json
await sheetContainer.Store("Save/Files/Path");

// later, load from json
await sheetContainer.Load("Save/Files/Path");

You can use processor parameter to customize serialization process.

Accessing Row

Below code shows how to access specific ItemSheet.Row.

var row = sheetContainer.Items["ITEM_LVUP003"];

// Assassin's dagger
logger.LogInformation(row.Name);

// loop through all rows
foreach (var value in sheetContainer.Items.Values)
    logger.LogInformation(value.Name);

Using Non-String Column as Id

Any type can be used value can be also used as Id. This is possible as passing type argument to generic class SheetRow<TKey> and Sheet<TKey, TRow>. Below is example content of file Contstants.xlsx.

Id Value
ServerAddress https://github.com/cathei/BakingSheet
InitialGold 1000
CriticalChance 0.1

Below code shows how to use enumeration type as Id.

public enum GameConstant
{
    ServerAddress,
    InitialGold,
    CriticalChance,
}

public class ConstantSheet : Sheet<GameConstant, ConstantSheet.Row>
{
    public class Row : SheetRow<GameConstant>
    {
        public string Value { get; private set; }
    }
}

Using Post Load Hook

You can override PostLoad method of Sheet, SheetRow or SheetRowElem to execute post load process.

Below code shows how to convert loaded sheet value dynamically.

public class ConstantSheet : Sheet<GameConstant, ConstantSheet.Row>
{
    public class Row : SheetRow<GameConstant>
    {
        public string Value { get; private set; }

        private int valueInt;
        public int ValueInt => valueInt;

        private float valueFloat;
        public float ValueFloat => valueFloat;

        public override void PostLoad(SheetConvertingContext context)
        {
            base.PostLoad(context);

            int.TryParse(Value, out valueInt);
            float.TryParse(Value, out valueFloat);
        }
    }

    public string GetString(GameConstant key)
    {
        return Find(key).Value;
    }

    public int GetInt(GameConstant key)
    {
        return Find(key).ValueInt;
    }

    public float GetFloat(GameConstant key)
    {
        return Find(key).ValueFloat;
    }
}

Note that properties without setter are not serialized. Alternatively you can use [JsonIgnore] attribute.

Using Row Array

Row arrays are used for simple nested structure. Below is example content of file Heroes.xlsx.

Id Name Strength Inteligence Vitality StatMultiplier RequiredExp RequiredItem
HERO001 Warrior 100 80 140 1 0
1.2 10
1.4 20
1.6 40
2 100 ITEM_LVUP001
HERO002 Mage 60 160 80 1 0
1.2 10
1.4 20
1.6 40
2 100 ITEM_LVUP002
HERO003 Assassin 140 100 80 1 0
1.2 10
1.4 20
1.6 40
2 100 ITEM_LVUP003

Rows without Id is considered as part of previous row. Below corresponding code shows how to define row arrays.

public class HeroSheet : Sheet<HeroSheet.Row>
{
    public class Row : SheetRowArray<Elem>
    {
        public string Name { get; private set; }

        public int Strength { get; private set; }
        public int Inteligence { get; private set; }
        public int Vitality { get; private set; }

        public Elem GetLevel(int level)
        {
            return this[level - 1];
        }
    }

    public class Elem : SheetRowElem
    {
        public float StatMultiplier { get; private set; }
        public int RequiredExp { get; private set; }
        public string RequiredItem { get; private set; }
    }
}

Note that SheetRowArray<TElem> is implementing IEnumerable<TElem> and indexer.

Using Cross-Sheet Reference

Below code shows how to replace string RequiredItem to ItemSheet.Reference RequiredItem to add extra reliablity. Sheet<TKey, TRow>.Reference type is serialized as TKey, and verifies that row with same id exists in the sheet.

public class HeroSheet : Sheet<HeroSheet.Row>
{
    public class Row : SheetRowArray<Elem>
    {
        // ...
    }

    public class Elem : SheetRowElem
    {
        public float StatMultiplier { get; private set; }
        public int RequiredExp { get; private set; }
        public ItemSheet.Reference RequiredItem { get; private set; }
    }
}
public class SheetContainer : SheetContainerBase
{
    // ...

    // use name of each matching sheet name from source
    public HeroSheet Heroes { get; private set; }
    public ItemSheet Items { get; private set; }
}

Note that both ItemSheet and HeroSheet have to be one of the properties on same SheetContainer class.

Custom Importers

User can create and customize their own importer by implementing ISheetImporter.

Custom Verifiers

You can verify datasheet sanity with custom verifiers. For example, you can define ResourceAttribute to mark columns that should reference path inside of Unity's Resources folder.

bakingsheet's People

Contributors

cathei avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.