summaryrefslogtreecommitdiffstats
path: root/xbmc/games/addons/input/GameClientTopology.cpp
blob: e1e9757c84524632a7e918511f1a4a50aa6752fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
 *  Copyright (C) 2017-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "GameClientTopology.h"

#include "GameClientDevice.h"
#include "GameClientPort.h"
#include "games/controllers/Controller.h"

#include <sstream>
#include <utility>

using namespace KODI;
using namespace GAME;

#define CONTROLLER_ADDRESS_SEPARATOR "/"

CGameClientTopology::CGameClientTopology(GameClientPortVec ports, int playerLimit)
  : m_ports(std::move(ports)), m_playerLimit(playerLimit), m_controllers(GetControllerTree(m_ports))
{
}

void CGameClientTopology::Clear()
{
  m_ports.clear();
  m_controllers.Clear();
}

CControllerTree CGameClientTopology::GetControllerTree(const GameClientPortVec& ports)
{
  CControllerTree tree;

  PortVec controllerPorts;
  for (const GameClientPortPtr& port : ports)
  {
    CPortNode portNode = GetPortNode(port, "");
    controllerPorts.emplace_back(std::move(portNode));
  }

  tree.SetPorts(std::move(controllerPorts));

  return tree;
}

CPortNode CGameClientTopology::GetPortNode(const GameClientPortPtr& port,
                                           const std::string& controllerAddress)
{
  CPortNode portNode;

  std::string portAddress = MakeAddress(controllerAddress, port->ID());

  portNode.SetConnected(false);
  portNode.SetPortType(port->PortType());
  portNode.SetPortID(port->ID());
  portNode.SetAddress(portAddress);
  portNode.SetForceConnected(port->ForceConnected());

  ControllerNodeVec nodes;
  for (const GameClientDevicePtr& device : port->Devices())
  {
    CControllerNode controllerNode = GetControllerNode(device, portAddress);
    nodes.emplace_back(std::move(controllerNode));
  }
  portNode.SetCompatibleControllers(std::move(nodes));

  return portNode;
}

CControllerNode CGameClientTopology::GetControllerNode(const GameClientDevicePtr& device,
                                                       const std::string& portAddress)
{
  CControllerNode controllerNode;

  const std::string controllerAddress = MakeAddress(portAddress, device->Controller()->ID());

  controllerNode.SetController(device->Controller());
  controllerNode.SetPortAddress(portAddress);
  controllerNode.SetControllerAddress(controllerAddress);

  PortVec ports;
  for (const GameClientPortPtr& port : device->Ports())
  {
    CPortNode portNode = GetPortNode(port, controllerAddress);
    ports.emplace_back(std::move(portNode));
  }

  CControllerHub controllerHub;
  controllerHub.SetPorts(std::move(ports));
  controllerNode.SetHub(std::move(controllerHub));

  return controllerNode;
}

std::string CGameClientTopology::MakeAddress(const std::string& baseAddress,
                                             const std::string& nodeId)
{
  std::ostringstream address;

  if (!baseAddress.empty())
    address << baseAddress;

  address << CONTROLLER_ADDRESS_SEPARATOR << nodeId;

  return address.str();
}