Exemplo n.º 1
0
    public static RethinkQueryStatus RethinkConnect(DatabaseCache cache, string connectionString, bool syncLocalChanges = true, bool filterGalaxyData = 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}");
            };
        }

        var status = new RethinkQueryStatus();

        // Get all item data from RethinkDB
        Task.Run(async() =>
        {
            status.ItemsEntries = R
                                  .Db("Aetheria")
                                  .Table("Items")
                                  .Count().RunAtom <int>(connection);

            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);
                status.RetrievedItems++;
            }
        }).WrapErrors();

        // Get globaldata and all galaxy map layer data from RethinkDB
        Task.Run(async() =>
        {
            ReqlAst operation = R
                                .Db("Aetheria")
                                .Table("Galaxy");
            if (filterGalaxyData)
            {
                var filter = ((Table)operation).Filter(o =>
                                                       o["$type"] == typeof(GalaxyMapLayerData).Name ||
                                                       o["$type"] == typeof(GlobalData).Name ||
                                                       o["$type"] == typeof(MegaCorporation).Name);
                status.GalaxyEntries = filter.Count().RunAtom <int>(connection);
                operation            = filter;
            }
            else
            {
                status.GalaxyEntries = ((Table)operation).Count().RunAtom <int>(connection);
            }

            var result = await operation
                         .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);
                status.RetrievedItems++;
            }
        }).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(status);
    }
Exemplo n.º 2
0
    public void OnGUI()
    {
        Event     currentEvent     = Event.current;
        EventType currentEventType = currentEvent.type;

        _view = BeginScrollView(
            _view,
            false,
            false,
            GUIStyle.none,
            GUI.skin.verticalScrollbar,
            GUI.skin.scrollView,
            GUILayout.Width(EditorGUIUtility.currentViewWidth),
            GUILayout.ExpandHeight(true));

        if (currentEventType == EventType.DragUpdated)
        {
            // Indicate that we don't accept drags ourselves
            DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
        }

        using (var h = new HorizontalScope())
        {
            _connectionString = TextField(_connectionString);
            if (GUILayout.Button("Connect"))
            {
                EditorPrefs.SetString("RethinkDB.URL", _connectionString);
                _queryStatus = RethinkConnection.RethinkConnect(_databaseCache, _connectionString);
            }
        }
        using (var h = new HorizontalScope())
        {
            if (GUILayout.Button("Connect All"))
            {
                EditorPrefs.SetString("RethinkDB.URL", _connectionString);
                _queryStatus = RethinkConnection.RethinkConnect(_databaseCache, _connectionString, true, false);
            }

            if (GUILayout.Button("Save"))
            {
                _databaseCache.Save(new DirectoryInfo(Application.dataPath).Parent.FullName);
            }
        }

        using (new HorizontalScope())
        {
            if (GUILayout.Button("Delete Orphaned Blueprints"))
            {
                int count = 0;
                foreach (var blueprintData in _databaseCache.GetAll <BlueprintData>().ToArray())
                {
                    if (_databaseCache.Get(blueprintData.Item) == null)
                    {
                        _databaseCache.Delete(blueprintData);
                        count++;
                    }
                }
                Debug.Log($"Deleted {count} orphaned blueprints!");
            }
        }

        if (_queryStatus != null && _queryStatus.RetrievedItems < _queryStatus.GalaxyEntries + _queryStatus.ItemsEntries)
        {
            var progressRect = GetControlRect(false, 20);
            EditorGUI.ProgressBar(progressRect, (float)_queryStatus.RetrievedItems / (_queryStatus.GalaxyEntries + _queryStatus.ItemsEntries), "Sync Progress");
        }
        // else
        // {
        //     if(_itemBlueprints == null)
        //         _itemBlueprints = _databaseCache.GetAll<ItemData>()
        //             .Select(itemData => new {itemData, blueprints = _databaseCache.GetAll<BlueprintData>()
        //                 .Where(blueprintData => blueprintData.Item == itemData.ID)
        //                 .Select(bp => bp.ID)
        //                 .ToList()})
        //             .ToDictionary(x => x.itemData.ID, x => x.blueprints);
        // }
        GUILayout.Space(5);

        // if(GUILayout.Button("Log Cache Count"))
        //     Debug.Log($"Cache contains {_databaseCache.AllEntries.Count()} elements");

        using (var h = new HorizontalScope(ListItemStyle))
        {
            _itemsFoldout = Foldout(_itemsFoldout, "Items", true);
        }
        if (_itemsFoldout)
        {
            var items = _databaseCache.AllEntries.Where(item => item is ItemData).Cast <ItemData>().ToArray();
            for (var i = 0; i < _itemTypes.Length; i++)
            {
                using (var h = new HorizontalScope(ListItemStyle))
                {
                    GUILayout.Space(10);
                    _itemTypeFoldouts[i] = Foldout(_itemTypeFoldouts[i],
                                                   ((NameAttribute)_itemTypes[i].GetCustomAttribute(typeof(NameAttribute)))?.Name ?? FormatTypeName(_itemTypes[i].Name),
                                                   true);
                }
                if (_itemTypeFoldouts[i])
                {
                    var typedItems = items.Where(e => e.GetType() == _itemTypes[i]).OrderBy(item => item.Name);
                    IEnumerable <IGrouping <string, ItemData> > itemGroups = new List <IGrouping <string, ItemData> >();
                    if (_itemTypes[i] == typeof(SimpleCommodityData))
                    {
                        itemGroups = typedItems.GroupBy(item => Enum.GetName(typeof(SimpleCommodityCategory), (item as SimpleCommodityData).Category));
                    }
                    else if (_itemTypes[i] == typeof(CompoundCommodityData))
                    {
                        itemGroups = typedItems.GroupBy(item => Enum.GetName(typeof(CompoundCommodityCategory), (item as CompoundCommodityData).Category));
                    }
                    else if (_itemTypes[i] == typeof(GearData))
                    {
                        itemGroups = typedItems.GroupBy(item => Enum.GetName(typeof(HardpointType), (item as GearData).Hardpoint));
                    }
                    else if (_itemTypes[i] == typeof(HullData))
                    {
                        itemGroups = typedItems.GroupBy(item => Enum.GetName(typeof(HullType), (item as HullData).HullType));
                    }

                    foreach (var itemGroup in itemGroups)
                    {
                        using (var h = new HorizontalScope(ListItemStyle))
                        {
                            GUILayout.Space(20);
                            if (Foldout(_itemGroupFoldouts.Contains(itemGroup.Key), FormatTypeName(itemGroup.Key), true))
                            {
                                _itemGroupFoldouts.Add(itemGroup.Key);
                            }
                            else
                            {
                                _itemGroupFoldouts.Remove(itemGroup.Key);
                            }
                        }

                        if (_itemGroupFoldouts.Contains(itemGroup.Key))
                        {
                            foreach (var item in itemGroup)
                            {
                                var style    = ListItemStyle;
                                var selected = SelectedItem == item.ID;
                                using (new HorizontalScope(selected?SelectedStyle:style))
                                {
                                    using (var h = new HorizontalScope())
                                    {
                                        if (h.rect.Contains(currentEvent.mousePosition))
                                        {
                                            if (currentEventType == EventType.MouseDrag)
                                            {
                                                DragAndDrop.PrepareStartDrag();
                                                DragAndDrop.SetGenericData("Item", item.ID);
                                                DragAndDrop.StartDrag("Database Item");
                                            }
                                            else if (currentEventType == EventType.MouseUp)
                                            {
                                                Select(item);
                                            }
                                        }

                                        GUILayout.Space(30);
                                        GUILayout.Label(item.Name, selected ? EditorStyles.whiteLabel : GUI.skin.label);
                                    }

                                    using (var h = new HorizontalScope(GUILayout.Width(15)))
                                    {
                                        if (GUI.Button(h.rect, GUIContent.none, GUIStyle.none))
                                        {
                                            if (_itemBlueprintFoldouts.Contains(item.ID))
                                            {
                                                _itemBlueprintFoldouts.Remove(item.ID);
                                            }
                                            else
                                            {
                                                _itemBlueprintFoldouts.Add(item.ID);
                                            }
                                        }
                                        GUILayout.Label(_itemBlueprints[item.ID].Count.ToString());
                                        var rect = GetControlRect(false, GUILayout.Width(EditorGUIUtility.singleLineHeight));
                                        if (Event.current.type == EventType.Repaint)
                                        {
                                            var controlId = GUIUtility.GetControlID(1337, FocusType.Keyboard, position);
                                            EditorStyles.foldout.Draw(rect, GUIContent.none, controlId, _itemBlueprintFoldouts.Contains(item.ID));
                                        }
                                    }
                                }

                                if (_itemBlueprintFoldouts.Contains(item.ID))
                                {
                                    foreach (var blueprintData in _itemBlueprints[item.ID]
                                             .Select(id => _databaseCache.Get <BlueprintData>(id))
                                             .OrderBy(bp => bp.Quality))
                                    {
                                        var blueprintStyle    = ListItemStyle;
                                        var blueprintSelected = SelectedItem == blueprintData.ID;
                                        using (var h = new HorizontalScope(blueprintSelected ? SelectedStyle : blueprintStyle))
                                        {
                                            if (h.rect.Contains(currentEvent.mousePosition))
                                            {
                                                if (currentEventType == EventType.MouseDrag)
                                                {
                                                    DragAndDrop.PrepareStartDrag();
                                                    DragAndDrop.SetGenericData("Item", blueprintData.ID);
                                                    DragAndDrop.StartDrag("Database Item");
                                                }
                                                else if (currentEventType == EventType.MouseUp)
                                                {
                                                    Select(blueprintData);
                                                }
                                            }

                                            GUILayout.Space(40);
                                            GUILayout.Label(blueprintData.Name,
                                                            blueprintSelected ? EditorStyles.whiteLabel : GUI.skin.label);
                                        }
                                    }

                                    using (var h = new HorizontalScope(ListItemStyle))
                                    {
                                        if (GUI.Button(h.rect, GUIContent.none, GUIStyle.none))
                                        {
                                            var blueprint = new BlueprintData
                                            {
                                                Item = item.ID,
                                                Name = item.Name
                                            };
                                            _databaseCache.Add(blueprint);
                                            Select(blueprint);
                                        }
                                        GUILayout.Space(40);
                                        GUILayout.Label("New Blueprint");
                                        var rect = GetControlRect(false, GUILayout.Width(EditorGUIUtility.singleLineHeight));
                                        GUI.DrawTexture(rect, Icons.Instance.plus, ScaleMode.StretchToFill, true, 1, LabelColor,
                                                        0, 0);
                                    }
                                }
                            }

                            using (var h = new HorizontalScope(ListItemStyle))
                            {
                                if (GUI.Button(h.rect, GUIContent.none, GUIStyle.none))
                                {
                                    CreateItem(_itemTypes[i], newItem =>
                                    {
                                        if (newItem is SimpleCommodityData simpleCommodityData)
                                        {
                                            simpleCommodityData.Category =
                                                (SimpleCommodityCategory)Enum.Parse(typeof(SimpleCommodityCategory),
                                                                                    itemGroup.Key);
                                            simpleCommodityData.Name = $"New {itemGroup.Key}";
                                        }
                                        else if (newItem is CompoundCommodityData compoundCommodityData)
                                        {
                                            compoundCommodityData.Category =
                                                (CompoundCommodityCategory)Enum.Parse(
                                                    typeof(CompoundCommodityCategory), itemGroup.Key);
                                            compoundCommodityData.Name = $"New {itemGroup.Key}";
                                        }
                                        else if (newItem is GearData gearData)
                                        {
                                            gearData.Hardpoint =
                                                (HardpointType)Enum.Parse(typeof(HardpointType), itemGroup.Key);
                                            gearData.Name = $"New {itemGroup.Key}";
                                        }
                                        else if (newItem is HullData hullData)
                                        {
                                            hullData.HullType = (HullType)Enum.Parse(typeof(HullType), itemGroup.Key);
                                            hullData.Name     = $"New {itemGroup.Key}";
                                        }
                                    });
                                }
                                GUILayout.Space(30);
                                GUILayout.Label("New " + itemGroup.Key);
                                var rect = GetControlRect(false, GUILayout.Width(EditorGUIUtility.singleLineHeight));
                                GUI.DrawTexture(rect, Icons.Instance.plus, ScaleMode.StretchToFill, true, 1, LabelColor, 0, 0);
                            }
                        }
                    }

                    if (!itemGroups.Any())
                    {
                        using (var h = new HorizontalScope(ListItemStyle))
                        {
                            if (GUI.Button(h.rect, GUIContent.none, GUIStyle.none))
                            {
                                CreateItem(_itemTypes[i]);
                            }
                            GUILayout.Space(20);
                            GUILayout.Label("New " + _itemTypes[i].Name);
                            var rect = GetControlRect(false, GUILayout.Width(EditorGUIUtility.singleLineHeight));
                            GUI.DrawTexture(rect, Icons.Instance.plus, ScaleMode.StretchToFill, true, 1, LabelColor, 0, 0);
                        }
                    }
                }
            }
        }

        var entries = _databaseCache.AllEntries.Where(item => !(item is ItemData)).ToArray();

        for (var i = 0; i < _entryTypes.Length; i++)
        {
            using (var h = new HorizontalScope(ListItemStyle))
            {
                _entryFoldouts[i] = Foldout(_entryFoldouts[i],
                                            ((NameAttribute)_entryTypes[i].GetCustomAttribute(typeof(NameAttribute)))?.Name ?? FormatTypeName(_entryTypes[i].Name),
                                            true);
            }

            if (_entryFoldouts[i])
            {
                int index = 0;
                foreach (var entry in entries.Where(e => e.GetType() == _entryTypes[i]).OrderBy(entry => entry is INamedEntry namedEntry ? namedEntry.EntryName : entry.ID.ToString()))
                {
                    index++;
                    var style    = ListItemStyle;
                    var selected = SelectedItem == entry.ID;
                    using (var h = new HorizontalScope(selected?SelectedStyle:style))
                    {
                        if (h.rect.Contains(currentEvent.mousePosition))
                        {
                            if (currentEventType == EventType.MouseDrag)
                            {
                                DragAndDrop.PrepareStartDrag();
                                DragAndDrop.SetGenericData("Item", entry.ID);
                                DragAndDrop.StartDrag("Database Item");
                            }
                            else if (currentEventType == EventType.MouseUp)
                            {
                                Select(entry);
                            }
                        }
                        GUILayout.Space(10);
                        GUILayout.Label((entry as INamedEntry)?.EntryName ?? index.ToString(), selected ? EditorStyles.whiteLabel : GUI.skin.label);
                    }
                }

                using (var h = new HorizontalScope(ListItemStyle))
                {
                    if (GUI.Button(h.rect, GUIContent.none, GUIStyle.none))
                    {
                        CreateItem(_entryTypes[i]);
                    }
                    GUILayout.Space(10);
                    GUILayout.Label("New " + _entryTypes[i].Name);
                    var rect = GetControlRect(false, GUILayout.Width(EditorGUIUtility.singleLineHeight));
                    GUI.DrawTexture(rect, Icons.Instance.plus, ScaleMode.StretchToFill, true, 1, LabelColor, 0, 0);
                }
            }
        }

        EndScrollView();
    }
Exemplo n.º 3
0
    public static RethinkQueryStatus RethinkConnect(CultCache cache, string connectionString, string dbName, bool syncLocalChanges = true)
    {
        // Add Unity.Mathematics serialization support to RethinkDB Driver
        JsonConvert.DefaultSettings = () => new JsonSerializerSettings
        {
            Converters = new List <JsonConverter>
            {
                new MathJsonConverter(),
                Converter.DateTimeConverter,
                Converter.BinaryConverter,
                Converter.GroupingConverter,
                Converter.PocoExprConverter
            }
        };

        var syncTables = typeof(DatabaseEntry).GetAllChildClasses()
                         .Select(t => t.GetCustomAttribute <RethinkTableAttribute>()?.TableName ?? "Default").Distinct();

        var connectionStringDomainLength = connectionString.IndexOf(':');

        if (connectionStringDomainLength < 1)
        {
            throw new ArgumentException("Illegal Connection String: must include port!");
        }

        var portString = connectionString.Substring(connectionStringDomainLength + 1);

        if (!int.TryParse(portString, out var port))
        {
            throw new ArgumentException($"Illegal connection string! \"{portString}\" is not a valid port number!");
        }

        var connection = R.Connection()
                         .Hostname(connectionString.Substring(0, connectionStringDomainLength))
                         .Port(port).Timeout(60).Connect();

        var tables = R.Db(dbName).TableList().RunAtom <string[]>(connection);

        foreach (var st in syncTables.Where(st => !tables.Contains(st)))
        {
            R.Db(dbName).TableCreate(st).RunNoReply(connection);
        }

        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(dbName)
                             .Table(table)
                             .Get(entry.ID)
                             .Replace(entry)
                             .RunAsync(connection);
            };

            cache.OnDataInsertLocal += async entry =>
            {
                var table  = entry.GetType().GetCustomAttribute <RethinkTableAttribute>()?.TableName ?? "Other";
                var result = await R
                             .Db(dbName)
                             .Table(table)
                             .Insert(entry)
                             .RunAsync(connection);
            };

            cache.OnDataRemoveLocal += async entry =>
            {
                var table  = entry.GetType().GetCustomAttribute <RethinkTableAttribute>()?.TableName ?? "Other";
                var result = await R
                             .Db(dbName)
                             .Table(table)
                             .Get(entry.ID)
                             .Delete()
                             .RunAsync(connection);
            };
        }

        var status = new RethinkQueryStatus();

        foreach (var table in syncTables)
        {
            // Get entries from RethinkDB
            Task.Run(async() =>
            {
                status.TotalEntries += R
                                       .Db(dbName)
                                       .Table(table)
                                       .Count().RunAtom <int>(connection);

                var result = await R
                             .Db(dbName)
                             .Table(table)
                             .RunCursorAsync <DatabaseEntry>(connection);
                while (await result.MoveNextAsync())
                {
                    var entry = result.Current;
                    cache.Add(entry, true);
                    status.RetrievedEntries++;
                }
            }).WrapAwait();

            // Subscribe to changes from RethinkDB
            Task.Run(async() =>
            {
                var result = await R
                             .Db(dbName)
                             .Table(table)
                             .Changes()
                             .RunChangesAsync <DatabaseEntry>(connection);
                while (await result.MoveNextAsync())
                {
                    var change = result.Current;
                    cache.Add(change.NewValue, true);
                }
            }).WrapAwait();
        }

        return(status);
    }