Aetheria/Assets/Scripts/RethinkConnection.cs
hyperion51 af88788e4f Local AI Testing & Interactive Tech Tab
Refactored game loop to allow full local testing
Added AI controller abstractions
Added ability to save database to local copy for offline testing
Tech Tab is now interactive, has properties panel
2020-04-23 03:31:17 +01:00

133 lines
5 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using Newtonsoft.Json;
using RethinkDb.Driver;
using RethinkDb.Driver.Net;
using UniRx;
using UnityEngine;
public static class RethinkConnection
{
public static RethinkDB R = RethinkDB.R;
public static Connection RethinkConnect(DatabaseCache cache, string connectionString, bool syncLocalChanges = true)
{
// Add Unity.Mathematics serialization support to RethinkDB Driver
//Converter.Serializer.Converters.Add(new MathJsonConverter());
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
Converters = new List<JsonConverter>
{
new MathJsonConverter(),
Converter.DateTimeConverter,
Converter.BinaryConverter,
Converter.GroupingConverter,
Converter.PocoExprConverter
}
};
var connection = R.Connection().Hostname(connectionString).Port(RethinkDBConstants.DefaultPort).Timeout(60).Connect();
Debug.Log("Connected to RethinkDB");
if (syncLocalChanges)
{
// When entries are changed locally, push the changes to RethinkDB
cache.OnDataUpdateLocal += async entry =>
{
var table = entry.GetType().GetCustomAttribute<RethinkTableAttribute>()?.TableName ?? "Other";
var result = await R
.Db("Aetheria")
.Table(table)
.Get(entry.ID)
.Replace(entry)
.RunAsync(connection);
Debug.Log($"Uploaded entry to RethinkDB: {entry.ID} result: {result}");
};
cache.OnDataInsertLocal += async entry =>
{
var table = entry.GetType().GetCustomAttribute<RethinkTableAttribute>()?.TableName ?? "Other";
var result = await R
.Db("Aetheria")
.Table(table)
.Insert(entry)
.RunAsync(connection);
Debug.Log($"Inserted entry to RethinkDB: {entry.ID} result: {result}");
};
cache.OnDataDeleteLocal += async entry =>
{
var table = entry.GetType().GetCustomAttribute<RethinkTableAttribute>()?.TableName ?? "Other";
var result = await R
.Db("Aetheria")
.Table(table)
.Get(entry.ID)
.Delete()
.RunAsync(connection);
Debug.Log($"Deleted entry from RethinkDB: {entry.ID} result: {result}");
};
}
// Get all item data from RethinkDB
Task.Run(async () =>
{
var result = await R
.Db("Aetheria")
.Table("Items")
.RunCursorAsync<DatabaseEntry>(connection);
while (await result.MoveNextAsync())
{
var entry = result.Current;
Debug.Log($"Received Items entry from RethinkDB: {entry.GetType()} {(entry as INamedEntry)?.EntryName ?? ""}:{entry.ID}");
cache.Add(entry, true);
}
}).WrapErrors();
// Get globaldata and all galaxy map layer data from RethinkDB
Task.Run(async () =>
{
var result = await R
.Db("Aetheria")
.Table("Galaxy")
//.Filter(o => o["$type"]==typeof(GalaxyMapLayerData).Name || o["$type"]==typeof(GlobalData).Name)
.RunCursorAsync<DatabaseEntry>(connection);
while (await result.MoveNextAsync())
{
var entry = result.Current;
Debug.Log($"Received Galaxy entry from RethinkDB: {entry.GetType()} {(entry as INamedEntry)?.EntryName ?? ""}:{entry.ID}");
cache.Add(entry, true);
}
}).WrapErrors();
// Subscribe to changes from RethinkDB
Task.Run(async () =>
{
var result = await R
.Db("Aetheria")
.Table("Items")
.Changes()
.RunChangesAsync<DatabaseEntry>(connection);
while (await result.MoveNextAsync())
{
var change = result.Current;
if(change.OldValue == null)
Debug.Log($"Received change from RethinkDB (Entry Created): {change.NewValue.ID}");
else if(change.NewValue == null)
Debug.Log($"Received change from RethinkDB (Entry Deleted): {change.OldValue.ID}");
else
Debug.Log($"Received change from RethinkDB: {change.NewValue.ID}");
cache.Add(change.NewValue, true);
}
}).WrapErrors();
Observable.Timer(DateTimeOffset.Now, TimeSpan.FromSeconds(60)).Subscribe(_ =>
{
Debug.Log(R.Now().Run<DateTime>(connection).ToString() as string);
});
return connection;
}
}