본문으로 건너뛰기

한 칸에 여러 값 — 합성 값과 비트셋

시트가 코드가 되는 모습으로


셀 하나에 적지만 값이 여럿인 타입이 둘 있습니다. 하나는 레코드가 되고, 하나는 정수가 됩니다.

벡터 · 회전 · 색입니다. 컬럼 하나에 적고, 코드에서는 성분을 가진 타입으로 받습니다.

테이블 Marker

[System.Serializable]
public partial class MarkerRecord
{
#region Values
/// <summary>
/// primary index
/// </summary>
public int Index => _index;

/// <summary>
/// three floats
/// </summary>
public PosEntry Pos => _pos;

/// <summary>
/// two ints
/// </summary>
public CellEntry Cell => _cell;

/// <summary>
/// four bytes
/// </summary>
public TintEntry Tint => _tint;
#endregion

/// <summary>One element of <see cref="Pos"/>.</summary>
[System.Serializable]
public struct PosEntry
{
/// three floats
public float X;
/// three floats
public float Y;
/// three floats
public float Z;

public override string ToString()
{
var sb = new StringBuilder("{");
sb.Append("\"X\":"); ToStringHelper.ToString(X, sb);
sb.Append(",\"Y\":"); ToStringHelper.ToString(Y, sb);
sb.Append(",\"Z\":"); ToStringHelper.ToString(Z, sb);
sb.Append("}");
return sb.ToString();
}
}

/// <summary>One element of <see cref="Cell"/>.</summary>
[System.Serializable]
public struct CellEntry
{
/// two ints
public int X;
/// two ints
public int Y;

public override string ToString()
{
var sb = new StringBuilder("{");
sb.Append("\"X\":"); ToStringHelper.ToString(X, sb);
sb.Append(",\"Y\":"); ToStringHelper.ToString(Y, sb);
sb.Append("}");
return sb.ToString();
}
}

/// <summary>One element of <see cref="Tint"/>.</summary>
[System.Serializable]
public struct TintEntry
{
/// four bytes
public int R;
/// four bytes
public int G;
/// four bytes
public int B;
/// four bytes
public int A;

public override string ToString()
{
var sb = new StringBuilder("{");
sb.Append("\"R\":"); ToStringHelper.ToString(R, sb);
sb.Append(",\"G\":"); ToStringHelper.ToString(G, sb);
sb.Append(",\"B\":"); ToStringHelper.ToString(B, sb);
sb.Append(",\"A\":"); ToStringHelper.ToString(A, sb);
sb.Append("}");
return sb.ToString();
}
}

#region Storage
internal int _index;
internal PosEntry _pos;
internal CellEntry _cell;
internal TintEntry _tint;
#endregion

#region ToString
public override string ToString()
{
var sb = new StringBuilder("{");
sb.Append("\"Index\":"); ToStringHelper.ToString(Index, sb);
sb.Append(",\"Pos\":"); ToStringHelper.ToString(Pos, sb);
sb.Append(",\"Cell\":"); ToStringHelper.ToString(Cell, sb);
sb.Append(",\"Tint\":"); ToStringHelper.ToString(Tint, sb);
sb.Append("}");
return sb.ToString();
}
#endregion
}

MarkerTable.cs

파일에는 성분마다 컬럼 하나로 저장됩니다. Pos.X · Pos.Y · Pos.Z 를 따로 적었을 때와 바이트가 같습니다 — 달라지는 것은 시트에 적는 품과 코드에서 읽는 모습뿐입니다.


bitset 은 플래그 최대 64개입니다. 생성된 코드에서 bigint 와 구별되지 않습니다 — 다른 것은 담는 값이 아니라 셀에서 받아들이는 표기입니다.

테이블 Access

[System.Serializable]
public partial class AccessRecord
{
#region Values
/// <summary>
/// primary index
/// </summary>
public int Index => _index;

/// <summary>
/// which bits
/// </summary>
public long Flags => _flags;

/// <summary>
/// the same value
/// </summary>
public long Same => _same;
#endregion

#region Storage
internal int _index;
internal long _flags;
internal long _same;
#endregion

#region ToString
public override string ToString()
{
var sb = new StringBuilder("{");
sb.Append("\"Index\":"); ToStringHelper.ToString(Index, sb);
sb.Append(",\"Flags\":"); ToStringHelper.ToString(Flags, sb);
sb.Append(",\"Same\":"); ToStringHelper.ToString(Same, sb);
sb.Append("}");
return sb.ToString();
}
#endregion
}

AccessTable.cs

FlagsSame 이 같은 타입입니다. 시트에서 0b1011 이라고 적을 수 있는 쪽이 bitset 이고, 빈 칸은 오류입니다 — 비트 패턴에 빈 칸이 뜻할 것이 없기 때문입니다.