【发布时间】:2014-12-24 18:20:55
【问题描述】:
我想交换一对嵌套的IObservables 的顺序,并对其发生方式有一些限制。
作为一个具体的(虽然有点做作)示例,假设有一个游戏服务器托管连续的在线多人游戏。玩家可以随时加入并在每个游戏中执行操作。以下类的工作实现提供了玩家在连续游戏中执行的操作的只读视图:
class GameServer
{
public IObservable<Game> Games { get { ... } }
}
class Game
{
public int GameId { get { ... } }
public IObservable<GamePlayer> Players { get { ... } }
}
class GamePlayer
{
public int PlayerId { get { ... } }
public IObservable<PlayerAction> PlayerActions { get { ... } }
}
在这些类中,有一个嵌套的 observable IObservable<IObservable<IObservable<PlayerAction>>>。这是给形式的信息:There are a series of games. Within each game a series of players joined. Each player performed a number of actions in the game。
我想做的是重新排列这些数据,以便它提供以下信息:There are a number of players. Since each player joined, a series of games have been played. Within each game, the player performed a number of actions. 这看起来像是以下方法的实现:
IObservable<Player> Players { get; }
使用以下类:
class Player
{
public Player(int playerId, IObservable<PlayerGame> games)
{
PlayerId = playerId;
Games = games;
}
public int PlayerId { get; private set; }
public IObservable<PlayerGame> Games { get; private set; }
}
class PlayerGame
{
public PlayerGame(int gameId, IObservable<PlayerAction> gameActions)
{
GameId = gameId;
GameActions = gameActions;
}
public int GameId { get; private set; }
public IObservable<PlayerAction> GameActions { get; private set; }
}
这不是提供一系列游戏并为每个人展示每个玩家所做的事情,而是提供一系列玩家并展示他们对连续游戏的参与。
还有一个额外要求:玩家加入后,应显示他们在每场后续游戏中的动作,无论他们在该游戏中是否做了任何事情(即,如果玩家在游戏中什么都不做,Player 在游戏开始时仍应推送新的PlayerGame,即使它的GameActions 从未推送过值。
我将如何使用GameServer.Games 作为相关数据的来源来实施Players?
(回应 DaveSexton 的 cmets:ID 代表什么,数据来自哪里以及程序工作的框架或环境并不重要。所有需要的数据都存在于GameServer 中, Game 和 GamePlayer 类。我只是不知道如何将其改组为 Player 表单。)
一个几乎可行的解决方案
为了更好地了解我的目标,这是一个几乎可行的解决方案。唯一的问题是,如果一个新游戏开始并且GameServer.Games 推送一个新的Game,Player.Games 不会相应地为每个现有玩家推送一个新的PlayerGame(我希望这样做)。
Players = gameServer.Games
.Select(g => g.Players.Select(p => new { g.GameId, p.PlayerId, p.PlayerActions }))
.Switch()
.GroupBy(t => t.PlayerId)
.Select(
group =>
new Player(group.Key, group.Select(t => new PlayerGame(t.GameId, t.PlayerActions))));
【问题讨论】:
-
您的具体问题是什么?
-
@DaveSexton 在最后添加了一个实际问题——我将如何使用
GameServer.Games作为数据源来实现Players? -
它不能基于提供的类型来完成(而且我不愿意假设你已经省略的类型)。
Games是Game的序列,其中包含GamePlayer的序列,而Players是Player的序列,其中包含PlayerGame的序列。GamePlayer和PlayerGame是完全不同的类型。 -
我想我明白你的意思了 -
Player和PlayerGame只是围绕它们的属性的简单包装类。如果我将第二组类更改为接口,也许它会使我的要求更清楚。 -
根据提供的信息,答案是否定的。与
Game类型及其相关类型相比,提议的Player类型及其相关类型是完全不同的类型。您还没有描述任何在它们之间进行转换的方法。如何从GamePlayer的列表中获取Player的列表?后者仅提供PlayerId属性,而不是Player类型的属性。
标签: c# system.reactive