Besoin d'info sur les struct

CoolsinusCoolsinus Membre
octobre 2013 modifié dans API UIKit #1

Bonjour à  tous,


 


Voilà  je travaille en ce moment sur l'integration de Real-Time Matches dans mon jeu avec Game Center, et comme il n'y a absolument rien sur internet et que le tutoriel de Ray Wenderlich date de 2 ans, je dois me contenter de la doc Apple sur le sujet.


 


Je dois envoyer des données aux autres joueurs et en recevoir. J'ai remarque que dans la doc Apple ils utilisaient des struct qu'ils convertissaient ensuite en NSData pour envoyer les données. 


 


Donc j'ai fais connaissance avec les struct, ça marche bien tranquille. Sauf que pour recevoir les données, ils font comme ca (*) : 



Packet *p = (Packet*)[data bytes];
if (p.messageKind == PositionMessage) {
}

Je dois comprendre que Packet est une struct principale et que d'après ca



PositionPacket msg;
msg.messageKind = PositionMessage;

il y a des sous-struct tels que PositionPacket et quand on reçoit les données on identifie chaque type de Packet avec une string messageKind.


 


Sauf que comment est ce que justement on fait un struct principal et ses "sous-struct" ? Parce que d'après (*) ils utilisent une struct parent pour récupérer les données dedans puis ils affinent le type de struct avec messageKind. 


 


Merci d'avance :)


Réponses

  • Salut,


     


    Examine le fichier header .h de la class Packet, tu auras tout simplement la structure complète de la classe

  • Et je trouve ca où ? Parce que avec ce que tu m'as dis j'ai tapé Packet reference class dans google mais ca donne rien. Et quand je tape Packet dans Xcode il ne me propose rien, donc pour lui ça n'existe pas, et aucune trace de Packet dans le doc non plus..


  • La classe Packet n'est pas un classe Apple, c'est fait par Ray Wenderlich



    //
    // Packet.h
    // Snap
    //
    // Created by Ray Wenderlich on 5/25/12.
    // Copyright (c) 2012 Hollance. All rights reserved.
    //

    const size_t PACKET_HEADER_SIZE;

  • Comment ça se fait qu'on trouve ça dans la doc Apple alors ? :o Et tu pourrais me filer le lien de la classe stp ? :) 




  • Comment ça se fait qu'on trouve ça dans la doc Apple alors ? :o Et tu pourrais me filer le lien de la classe stp ? :)




     


    Voila le lien http://www.raywenderlich.com/12976/how-to-make-a-simple-playing-card-game-with-multiplayer-and-bluetooth-part-7`


     


    Pour la class Packet, je suis plutôt dev OSX que IOS donc je suis pas sur de ma réponse :)

  • Mais je suis pas sur que Packet.h du site Ray Wenderlich et Packet de la doc Apple ce soit la même chose..




  • Mais je suis pas sur que Packet.h du site Ray Wenderlich et Packet de la doc Apple ce soit la même chose..




     


    Sélectionnes le mot Packet dans l'éditeur XCode puis clique sur le bouton droit de la souris puis choisis


     


    "Jump to Definition" qui va ouvrir le fichier .h correspondant !

  • AliGatorAliGator Membre, Modérateur

    Sélectionnes le mot Packet dans l'éditeur XCode puis clique sur le bouton droit de la souris puis choisis
     
    "Jump to Definition" qui va ouvrir le fichier .h correspondant !

    Ou Commande-Clic directement sur le mot clé "Packet" dans le code, ça fait la même chose.
    (Et Alt-Clic pour voir le QuickHelp sur la structure Packet, Alt-Double-Clic pour voir la doc sur Packet)
  • CoolsinusCoolsinus Membre
    octobre 2013 modifié #10

    "Symbol not found" : quand j'entre Packet, Xcode ne me propose rien, donc quand j'écris Pa y'a pas Packet dans la liste de complétion qui apparait.. Xcode ne le connait pas quoi :p


  • Salut,


     


    Packet et ... ne sont pas des classes Apple, c'est juste des exemples pour expliquer comment envoyer des données ( sous forme de structures,...) et comment recevoir ces données. Leurs objectif c'est juste d'expliquer les méthodes principales avec des simple exemples :


     




    - (void) sendPosition
    {
    NSError *error;
    PositionPacket msg;
    msg.messageKind = PositionMessage;
    msg.x = currentPosition.x;
    msg.y = currentPosition.y;
    NSData *packet = [NSData dataWithBytes:&msg length:sizeof(PositionPacket)];
    [match sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable
    error:&error];
    if (error != nil)
    {
    // Handle the error.
    }
    }

    La par exemple PositionPacket est une structure mais tu peux construire ton packet ( NSData) juste avec un entier,... selon tes besoins, mais généralement une structure pour contenir plus d'informations.


     


    Le site de ray wanderlich se base bien sur la documentation d'Apple pour leurs tutorials...


     


  • C'est bien ce que je pensais et c'est d'ailleurs ce que je disais au début :p Est ce que vous pouvez justement me dire si on peut créer des sortes de structures principales tel que MyMainPacket qui, quand les données sont reçues, récupère les données, et en fonction du messageKind, crée une struct spécifique qui est une "sous-struct" de MyMainPacket qui reprenne les informations et qu'ensuite on puisse les traiter ?


  • Salut,


     


    Si tu veux une structure imbriquée et plus compliquée pars plutôt sur des objets. Par exemple :



    #import "UneAutreCalsse.h"
    // Tu déclare par exemple un type enum pour contenir le type de ton packet, "MessageKind",....

    typedef enum {
       kPacketTypeMessage,
    ...
    } PacketType;

    @interface ;MyMainPacket : NSObject

    @property (nonatomic, assign) PacketType type;
    ....
    @property (nonatomic, strong) UneAutreClasse *autreClasse

    @end

    la dans la MyMainPacket tu peux avoir des références sur d'autres structures de données ( structure C, autre classes,....). "UneAutreClasse" par exemple peux une sous classe de NSObject qui vas contenir des autres infos.



    @interface UneAutreClasse : NSObject

    @property (nonatomic, strong) NSString *playerName;
    ....
    @end

    et la quand tu vas recevoir ton objet MyMainPacket et en fonction de son type tu peux remplir la structure ( objet)  autreClasse.


     


    J'espère que j'était clair, sinon le mieux c'est que tu met ton code et nous dire ou tu bloque exactement.

  • AliGatorAliGator Membre, Modérateur
    Je te conseille de suivre quelques tutos en C sur les struct comme sur autre choses. Tu y apprendras plein de trucs utiles dans ce domaine, car toutes ces questions que tu te poses sont du C pur.

    Perso moi je ferai un truc dans ce genre là  :
    typedef struct {
    int messageKind;
    } PacketHeader;

    typedef struct {
    PacketHeader header;
    int champ1;
    double champ2;
    } PacketKind1;

    typedef struct {
    PacketHeader header;
    float champ1;
    long champ2;
    int champ3;
    } PacketKind2;

    PacketHeader packet = ...
    if (packet.messageKind == 1)
    {
    PacketKind1 p1 = (PacketKind1)packet;
    int c = p1.champ1;
    ...
    } else if (packet.messageKind == 2) {
    PacketKind2 p2 = (PacketKind2)packet;
    int c = p2.champ3;
    ...
    }
    Bon j'ai pas vérifié/testé, c'est fait en live mais bon c'est pour l'idée.
  • @samir2303 : merci de m'avoir répondu, même si je dois avouer que c'est plus quelque chose comme AliGator m'a donné que je cherchais. En gros avoir une structure générique qui récupère les données et qui affine en fonction du messageKind :)


     


    @AliGator : puai c'est bien un truc comme ça que je cherchais, bah je vais tester et je te tien au courant ;)

  • CoolsinusCoolsinus Membre
    octobre 2013 modifié #16

    Bon petit compte rendu : 


     


    Au final je fais comme ca : 



    typedef enum
    {
    kBeginningMessage = 0,
    kInProgressMessage,
    kEndingMessage
    } MessageKind

    typedef struct
    {
    MessageKind message;
    ...
    } myStruct


    Et pour ceux qui chercheraient comment passer un NSString dans une struct à  envoyer puis le récupérer voilà  :



    typedef struct
    {
    char string[20];
    } aStruct;

    -(void)aMethod
    {
    aStruct myStruct;
    NSString *stringToSend = @stringToSend;

    for (int i = 0; i < stringToSend.length; i++) {
    aStruct.string[i] = [stringToSend characterAtIndex:i];
    }

    NSData *data = [NSData dataWithBytes:&aStruct length:sizeof(myStruct)];

    myStruct *anotherStruct = (myStruct *)[data bytes];

    NSString *receivedString = [NSString stringWithUTF8String:anotherStruct->string];
    }

    Voilà . Merci pour votre aide :)


     


    EDIT : en fait ça marche pas bien parce que quand aStruct.string est initialisée elle se remplit de caractères et donc quand on remplace que la moitié, bah les autres après sont toujours là  et donne des trucs..bizarre.. :P


     


    EDIT 2 : en fait je fais comme ca et ca marche : 



    typedef struct {
    char string[100];
    int stringLength;
    } myStruct;


    myStruct aStruct;


        NSString *stringToConvert = @str;


        


        NSLog(@stringToConvert length : %i, stringToConvert.length);


        NSLog(@original string : %s, aStruct.string);


        


        for (int i = 0; i < stringToConvert.length; i++) {


            aStruct.string = [stringToConvert characterAtIndex:i];


        }


        aStruct.stringLength = stringToConvert.length;


        


        NSLog(@string after modifs : '%s', aStruct.string);


        


        NSData *data = [NSData dataWithBytes:&aStruct length:sizeof(myStruct)];


        


        myStruct *receiverStruct = (myStruct *)[data bytes];


        


        NSString *stringReceived = [[NSString alloc] initWithBytes:receiverStruct->string length:receiverStruct->stringLength encoding:NSASCIIStringEncoding];


        


        NSLog(@string after bytes range : '%@'", stringReceived);


     

     et ca donne : 


     


    stringToConvert length : 3


    original string : f ffà¿E


    string after modifs : 'str ffà¿E'


    string after bytes range : 'str'

Connectez-vous ou Inscrivez-vous pour répondre.