- Adicione recursos da v4 a um aplicativo criado com base em uma versão de API anterior, como a v0, sem migrar o aplicativo inteiro de uma só vez.
- Chame SDKs, middleware ou plug-ins de mecanismo que foram compilados com uma versão anterior do GameInput, mesmo quando o restante do seu aplicativo usa a v4.
Versões de API compatíveis
Um runtime do GameInput é compatível com todas as versões de API menores ou iguais à sua própria versão principal. Por exemplo, com o runtime do GameInput 4.0 instalado, todo objeto do GameInput implementa as interfaces v0, v1, v2, v3 e v4, e seu aplicativo pode usar qualquer combinação delas.
Se você solicitar uma versão de API mais recente do que o runtime instalado,
QueryInterface e GameInputInitialize falharão com E_NOINTERFACE. A versão de API mais alta que seu aplicativo usa determina a versão mínima do runtime que ele exige.
No PC, o runtime instalado é o redistribuível do GameInput ou um runtime que você implanta com o seu jogo. Para obter mais informações, confira Pacote NuGet do GameInput e Sideload do GameInput. No XBOX, o runtime está incluído no GDK, e você também pode implantar um runtime mais recente com o seu jogo. Para obter mais informações, confira GameInput em consoles XBOX.
Configurar seu projeto
Para novas implementações, use os cabeçalhos e oGameInput.lib do pacote NuGet Microsoft.GameInput mais recente. No pacote, <GameInput.h> é o cabeçalho mais recente, e cada cabeçalho anterior fica em uma pasta com versão, como <v0/GameInput.h> ou <v2/GameInput.h>. A biblioteca exporta GameInputInitialize, que cria o GameInput para qualquer versão de API que você solicitar.
Bibliotecas de versões anteriores, como a do GDK, também continuam funcionando. Para obter mais informações, confira Manter uma biblioteca anterior.
Incluir o cabeçalho v0
A partir da v1, cada cabeçalho do GameInput declara seus tipos em um namespace com versão, comoGameInput::v4. Já o cabeçalho v0 declara seus tipos no namespace global. Para usar o cabeçalho v0 junto com o cabeçalho mais recente, coloque o seguinte código clichê em um cabeçalho próprio, como GameInputV0.h:
- Ele inclui primeiro o
<GameInput.h>mais recente. Isso declara a API mais recente em seu próprio namespace e inclui os cabeçalhos do Windows e do COM dos quais o cabeçalho v0 depende, para que o cabeçalho v0 não os inclua novamente dentro do namespace. - As declarações antecipadas fazem com que os typedefs do cabeçalho v0 declarem novas interfaces em
GameInput::v0, em vez de se referirem a interfaces que o cabeçalho mais recente já declarou. - Incluir
<v0/GameInput.h>dentro do namespace move todos os tipos, enumerações e constantes da v0 paraGameInput::v0, comoGameInput::v0::IGameInputeGameInput::v0::GameInputKindGamepad.
GameInputV0.h em vez de <GameInput.h> e adicione using namespace GameInput::v0; para que o código existente possa continuar usando nomes não qualificados. Qualquer arquivo de origem que inclua GameInputV0.h também pode usar a API mais recente pelo nome completo, como GameInput::v4::IGameInput.
Exemplo: adicionar recursos da v4 a um aplicativo v0
Você não precisa reescrever seu código v0 para começar a usar recursos da v4. Mantenha o código v0 em seus próprios arquivos de origem e coloque o novo código v4 em arquivos de origem separados. Passe os objetos do GameInput entre os dois comoIUnknown* e faça com que cada lado chame QueryInterface para obter a versão de que precisa.
Código v0 existente
O código v0 a seguir cria o GameInput e lê o gamepad. Em comparação com o código v0 original, apenas três coisas mudam:- Ele inclui
GameInputV0.hem vez de<GameInput.h>. - Ele cria o GameInput chamando
GameInputInitializecom o IID da v0, porque a biblioteca mais recente não exporta a funçãoGameInputCreateda v0. - Ele chama o novo código v4 quando o botão A é pressionado.
Novo código v4
O novo arquivo de origem inclui o cabeçalho v4 e chamaQueryInterface no dispositivo que o código v0 passa. Em seguida, ele altera a cor da luz central do controle com IGameInputDevice::SetLightingColor e IGameInputDevice::ApplyLightingColors, que são novos na v4. Se o dispositivo não tiver uma luz central, a chamada será ignorada.
QueryInterface falhar, o runtime instalado não é compatível com a v4. Seu código v0 continua funcionando, e seu aplicativo pode ignorar os recursos da v4.
Quando todo o seu código usar a v4, você poderá remover GameInputV0.h e as chamadas para QueryInterface.
Manter uma biblioteca anterior
Se você continuar vinculando uma biblioteca de uma versão anterior, como a do GDK, seu código v0 existente não precisará mudar nada. Continue incluindo o cabeçalho v0 dessa versão e chamandoGameInputCreate. Essa chamada é encaminhada para o runtime instalado, portanto, quando o runtime for 4.0 ou posterior, o objeto que ele retorna também implementará as interfaces v4, e o novo código v4 mostrado anteriormente funcionará sem alterações.
Bibliotecas anteriores não exportam GameInputInitialize. Obtenha interfaces v4 somente chamando QueryInterface e não chame o GameInputCreate da v4, que chama GameInputInitialize.
Regras para alternar entre versões
Interfaces de diferentes versões de API têm os mesmos nomes, comoIGameInput e IGameInputDevice, mas são tipos diferentes com métodos diferentes. Um ponteiro para uma interface v0 não é um ponteiro para uma interface v4, embora ambos se refiram ao mesmo objeto.
Fazer uma conversão (cast) não é o mesmo que chamar
QueryInterface. Sempre use QueryInterface para obter uma interface de outra versão de API. Nunca use static_cast, reinterpret_cast ou uma conversão no estilo C para converter entre versões. Uma conversão compila, mas chamar um método por meio do ponteiro convertido pode chamar o método errado, o que leva a um comportamento indefinido.- Não inclua outro cabeçalho do GameInput depois do cabeçalho v0. O cabeçalho v0 define seus códigos de erro, como
GAMEINPUT_E_DEVICE_DISCONNECTED, como macros, e essas macros quebram as declarações de qualquer cabeçalho do GameInput incluído depois dele.GameInputV0.hsegue essa regra incluindo primeiro o cabeçalho mais recente. - Os objetos retornados usam a versão que você chamou. Por exemplo,
GetDeviceem uma leitura v4 retorna um dispositivo v4, e um retorno de chamada de dispositivo registrado com oIGameInputda v4 recebe dispositivos v4. ChameQueryInterfaceantes de passar esses objetos para um código que usa outra versão. - Cada chamada para
QueryInterfaceadiciona uma referência. Libere o ponteiro retornado quando não precisar mais dele, assim como qualquer outro ponteiro de interface COM. - Verifique o resultado. Quando você solicita uma versão de API mais recente, uma falha significa que o runtime instalado não é compatível com essa versão.
- Os tipos v0 em
GameInputV0.hsão tipos C++ separados.GameInput::v0::IGameInpute oIGameInputglobal de<v0/GameInput.h>sozinho descrevem a mesma interface, mas o C++ os trata como tipos diferentes. Se um código existente ou outra biblioteca declarar funções com os tipos v0 globais, chame essas funções a partir de um arquivo de origem que inclua somente<v0/GameInput.h>.
Chamar SDKs que usam uma versão de API anterior
Alguns SDKs, middleware e plug-ins de mecanismo são compilados com uma versão específica da API GameInput e esperam interfaces do GameInput dessa versão. Seu aplicativo pode usar uma versão mais recente e ainda assim chamar esses componentes. ChameQueryInterface para obter a versão que o componente espera e passe esse ponteiro.
Coloque a chamada em um arquivo de origem que inclua o mesmo cabeçalho do GameInput usado pelo componente. No exemplo a seguir, ThirdPartySdk.h declara ThirdPartySdkInitialize(GameInput::v2::IGameInput*), e o restante do aplicativo passa seu objeto do GameInput como IUnknown*:
QueryInterface nele para obter a interface v4.
Como todas as versões são implementadas pelo mesmo objeto, o SDK e o seu aplicativo compartilham dispositivos, leituras e estado. A versão de API do SDK também deve ser menor ou igual à versão do runtime instalado.
Confira também
Controle de versão da API do GameInputPacote NuGet do GameInput
Sideload do GameInput
GameInputInitialize
Referência da API do GameInput
