Ir ao conteúdo
  • Cadastre-se

C Detectar alteração em vetor de struct


_FBO_
Ir à solução Resolvido por arfneto,

Posts recomendados

Olá. Estou com dificuldade num código e preciso de ajuda...

Tenho vetores de structs e um ponteiro para o vetor que está em uso (variavel "item" no codigo abaixo).

Estou com essas dificuldades:

1. contar quantos itens tem em cada estrutura (veja variavel "qtd_items" no codigo abaixo)

2. como gerar um vetor clone (veja variavel "mirror" no codigo abaixo) que serve para monitorar alterações nas variaveis do vetor de "estrutura_t". Talvez pense: "mas dá pra saber quando o usuario faz alguma alteração de valores no código então não precisa ter um clone dos valores pra isso". Mas na verdade essas alterações não vão se limitar a operações de usuario, podem vir por causas externas (imagine que uma variavel apontada em uma das estruturas seja uma variavel de leitura de um sinal de sensor ou um contador de eventos de interrupção do sistema, então não dá pra saber quando houve alteração então por isso preciso de um clone da estrutura em uso para monitorar quando houver alterações pra poder salvar).

3. melhorias para a estrutura "item_t" também são bem-vindas, não sei se preciso dela para indicar qual vetor de "estrutura_t" está em uso, tentei de outra maneira mas não consegui compilar...

Muito obrigado

 

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

//definicoes
#define UINT 0
#define ULONG 1
#define FLOAT 3

//declaracao de estruturas
typedef struct{
  char *descricao;
  void *variavel;
  char tipo;
}estrutura_t;

typedef struct{
  estrutura_t *estrutura;
  char dummy;
}item_t;

union FloatBytes{
    float f;
    unsigned char bytes[4];
};

//declaracao de variaveis
unsigned int uint1,uint2,uint3;
unsigned long ulong1,ulong2,ulong3;
float float1,float2,float3;
item_t *item; //ponteiro que indica a estrutura em uso
item_t *mirror; //variavel que contem uma copia da estrutura em uso
int qtd_items,current_index;

//declaracao e inicializacao de vetores
estrutura_t estrutura0[4]= {
  {"primeiro item", &uint1, UINT},
  {"segundo item", &uint2, UINT},
  {"terceito item", &float1, FLOAT},
  {NULL,NULL,NULL}
};

estrutura_t estrutura1[6]= {
  {"descricao da linha 1", &ulong1, ULONG},
  {"conteudo da linha 2", &float2, FLOAT},
  {"qualquer conteudo aqui", &uint3, UINT},
  {"texto informativo", &ulong2, ULONG},
  {"quinta linha", &uint3, UINT},
  {NULL,NULL,NULL}
};

item_t item_tab[2]={
  {estrutura0,0},
  {estrutura1,0},
};


void load_values(void)
{
    int i,j;
    FILE *fp;
    char filename[10];
    unsigned char buffer[4];

    for(i=0; i<2; i++)
    {
        item= &item_tab[i];

        //descobre quantos itens tem no vetor de estrutura apontado por "item"
        //aqui eu precisava de um jeito melhor de descobrir a quantidade de itens
        qtd_items=0;
        for(j=0; j<100; j++)
        {
            if(item->estrutura[j].descricao != NULL)
                qtd_items++;
            else
                break;
        }

        //agora carrega o arquivo que contem os valores das estruturas
        sprintf(filename,"file_%d.bin", i);
        fp= fopen(filename, "rb");
        if(fp != NULL)
        {
            for(j=0; j<qtd_items; j++)
            {
                if(item->estrutura[j].tipo == UINT)
                {
                    unsigned int temp_word;
                    fread(buffer,2,1,fp);
                    temp_word= buffer[0] << 8 | buffer[1];
                    *(unsigned int*)item->estrutura[j].variavel= temp_word;
                }
                else
                if(item->estrutura[j].tipo == ULONG)
                {
                    unsigned long temp_long;
                    fread(buffer,4,1,fp);
                    temp_long= buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
                    *(unsigned long*)item->estrutura[j].variavel= temp_long;
                }
                else
                if(item->estrutura[j].tipo == FLOAT)
                {
                    union FloatBytes fb;
                    fread(fb.bytes,4,1,fp);
                    *(float*)item->estrutura[j].variavel= fb.f;
                }
            }
            fclose(fp);
        }
    }
}

void printa(void)  //printa a estrutura em uso
{
    int i;
    for(i=0; i<qtd_items; i++)
    {
        if(item->estrutura[i].tipo == UINT)
            printf("\r\n[%d] %s= %u", i, item->estrutura[i].descricao, *(unsigned int*)item->estrutura[i].variavel);
        else
        if(item->estrutura[i].tipo == ULONG)
            printf("\r\n[%d] %s= %lu", i, item->estrutura[i].descricao, *(unsigned long*)item->estrutura[i].variavel);
        else
        if(item->estrutura[i].tipo == FLOAT)
            printf("\r\n[%d] %s= %f", i, item->estrutura[i].descricao, *(float*)item->estrutura[i].variavel);
    }
}

void gerencia_alteracoes(void)
{
    int number;
    do{
        printf("\r\nDeseja alterar qual variavel? (Insira -1 para cancelar): ");
        scanf("%d", &number);
        if(number == -1)
          return;
    }while(number < 0 || number > qtd_items);

    if(item->estrutura[number].tipo == UINT)
    {
        printf("\r\n[%d] %s= %u", number,
                                  item->estrutura[number].descricao,
                                  *(unsigned int*)item->estrutura[number].variavel);
        printf("\r\nInsira o novo valor: ");
        scanf("%u",(unsigned int*)item->estrutura[number].variavel);
    }
    else
    if(item->estrutura[number].tipo == ULONG)
    {
        printf("\r\n[%d] %s= %lu", number,
                                   item->estrutura[number].descricao,
                                   *(unsigned long*)item->estrutura[number].variavel);
        printf("\r\nInsira o novo valor: ");
        scanf("%lu",(unsigned long*)item->estrutura[number].variavel);
    }
    else
    if(item->estrutura[number].tipo == FLOAT)
    {
        printf("\r\n[%d] %s= %f", number,
                                  item->estrutura[number].descricao,
                                  *(float*)item->estrutura[number].variavel);
        printf("\r\nInsira o novo valor: ");
        scanf("%f",(float*)item->estrutura[number].variavel);
    }
}

void salva_alteracoes(void)
{
    int i;
    char changed= 0;

    for(i=0; i<qtd_items; i++)
    {
        if(item->estrutura[i].tipo == UINT)
        {
            unsigned int ui1= *(unsigned int*)item->estrutura[i].variavel;
            unsigned int ui2= *(unsigned int*)mirror->estrutura[i].variavel;
            if(ui1 != ui2)
            {
               *(unsigned int*)mirror->estrutura[i].variavel= ui1;
               changed= 1;
               break;
            }
        }
        else
        if(item->estrutura[i].tipo == ULONG)
        {
            unsigned long ul1= *(unsigned long*)item->estrutura[i].variavel;
            unsigned long ul2= *(unsigned long*)mirror->estrutura[i].variavel;
            if(ul1 != ul2)
            {
               *(unsigned long*)mirror->estrutura[i].variavel= ul1;
               changed= 1;
               break;
            }
        }
        else
        if(item->estrutura[i].tipo == FLOAT)
        {
            float f1= *(float*)item->estrutura[i].variavel;
            float f2= *(float*)mirror->estrutura[i].variavel;
            if(fabs(f1 - f2) < 0.001)
            {
               *(float*)mirror->estrutura[i].variavel= f1;
               changed= 1;
               break;
            }
        }
    }

    if(changed)
    {
        FILE *fp;
        char filename[10];
        unsigned char buffer[4];

        sprintf(filename, "file_%d.bin", current_index);
        fp= fopen(filename,"wb");

        for(i=0; i<qtd_items; i++)
        {
            if(item->estrutura[i].tipo == UINT)
            {
                buffer[0]= *(unsigned int*)item->estrutura[i].variavel >> 8;
                buffer[1]= *(unsigned int*)item->estrutura[i].variavel & 0xFF;
                fwrite(buffer,1,2,fp);
            }
            else
            if(item->estrutura[i].tipo == ULONG)
            {
                buffer[0]= *(unsigned long*)item->estrutura[i].variavel >> 24;
                buffer[1]= *(unsigned long*)item->estrutura[i].variavel >> 16;
                buffer[2]= *(unsigned long*)item->estrutura[i].variavel >> 8;
                buffer[3]= *(unsigned long*)item->estrutura[i].variavel & 0xFF;
                fwrite(buffer,1,4,fp);
            }
            else
            if(item->estrutura[i].tipo == FLOAT)
            {
                union FloatBytes fb;
                fb.f= *(float*)item->estrutura[i].variavel;
                fwrite(fb.bytes,1,4,fp);
            }
        }
        fclose(fp);
    }
}

void main(void)
{
    int i;

    //carrega dados armazenados em arquivo para os vetores de "estrutura_t"
    load_values();

    while(1)
    {
        //permite selecionar uma estrutura para visualizar/alterar
        do{
            printf("\r\nQual menu deseja visualizar (0 ou 1)?  Insira -1 para sair: ");
            scanf("%d", &current_index);
            if(current_index == -1)
            {
                free(mirror);
                return;
            }
        }while(current_index < 0 || current_index > 1);

        //usuario selecionou uma estrutura, carrega-a
        item= &item_tab[current_index];
        qtd_items= 0;
        for(i=0; i<100; i++)
        {
            if(item->estrutura[i].descricao != NULL)
                qtd_items++;
            else
                break;
        }

        //aqui preciso criar a copia mas não sei como pois o conteudo é variavel
        free(mirror);
        mirror= (item_t*)malloc(sizeof(???));
        memcpy(mirror,item,sizeof(???));

        //apresenta o conteudo da estrutura em uso
        printa();

        //permite alterar o valor das variaveis da estrutura em uso
        gerencia_alteracoes();

        //compara se houver alteração em relação ao mirror e salva
        salva_alteracoes();
    }
}


 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Acho que seu programa ainda está longe de estar pronto e não devia escrever desse modo. Vai ter muito trabalho para usar, nem vai poder reusar. Está frágil demais e tem variáveis globais então as funções de pouco servem. Sugiro repensar.

Antes de tudo entenda que funções void f(void) são um desastre. NUNCA use isso. Retornar void já é um desperdício se não for um erro.

EEsse é o outro lado de usar coisas globais.

 

Para um exemplo simples, se tem uma estrutura espelhada como quer suas funções poderiam acesar com segurança todas as estruturas sem dependere de truques --- mais fragilidade --- como ponteiros externos.

 

1 hora atrás, _FBO_ disse:

contar quantos itens tem em cada estrutura

 

Pois é: um problema de construção. Isso deveria estar dentro da estrutura. Está complicando tudo

 

1 hora atrás, _FBO_ disse:

Mas na verdade essas alterações não vão se limitar a operações de usuario, podem vir por causas externas (imagine que uma variavel apontada em uma das estruturas seja uma variavel de leitura de um sinal de sensor ou um contador de eventos de interrupção do sistema, então não dá pra saber quando houve alteração então por isso preciso de um clone da estrutura em uso para monitorar quando houver alterações pra poder salvar)

 

Você está falando de memória compartilhada com dispositivos conectados, de modo que uma leitura vai para aí sem depender do seu programa?

 

Se apenas o seu programa acessa isso se o programa cancelar tudo se perde. E enquanto não cancelar o comum nesse caso é gravar um arquivo  journal ou log ou seja lá qual for o nome, onde você grava um timestamp - data e hora, a operação e o valor e lá vão estar as alterações via programa. Se o programa cancela você apenas abre esse arquivo e a versão anterior e reaplica tudo que está lá. E no caso de reabertura do sistema você verifica se houve registro de fechamento ok e então descarta o log ou reaplica tudo conforme o caso

 

Se há outras maneiras fora do programa de acessar isso precisa pensar melhor porque

  • pode vir uma leitura idêntica e você nem ficar sabendo. Mas pode ser importante saber que veio a mesma coisa
  • pode haver concorrência no acesso, como em programas multithread
  • seu programa sequer grava a data das entradas de dados então um processo de recovery não é assim seguro

 

 

2 horas atrás, _FBO_ disse:

então não dá pra saber quando houve alteração

 

Pergunto de novo: se a estrutura é montada dentro desse programa não é mesmo esse programa a a única maneira de alterar algo ali? Escreva uma API mais sólida apenas.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Agradeço as considerações. Realmente faltou eu explicar algo: este aplicativo que apresentei foi com o intuito de exemplificar o problema que tenho em um programa embarcado. Então eu extraí trechos do código e montei este aplicativo de exemplo para que possam visualizar o problema principal: ter um espelho do conteúdo do vetor da estrutura apontada pela variável "item". E no vetor pode ter variaveis que em outro trecho do programa terão seu valor alterado por leitura de periféricos como sensores. O objetivo final é utilizar as estruturas como a interface central, onde posso apenas acrescentar uma nova linha referenciando uma variavel que poderá ser utilizada para apresentar ao usuario a leitura de algum sensor ou permitir que o usuario altere o valor de variaveis. Porém, por ser um sistema embarcado, não quero ficar reapresentando toda a tabela para o usuario se não houver atualização, posso enviar apenas as variaveis que tiveram seus valores modificados, seja por propria entrada do usuario ou seja por atualização proveniente de outras partes do programa. Com isso planejo economizar tempo de processamento do sistema.

Eu não quero tambem consumir memória desnecessaria fazendo um espelho de todos os vetores de "estrutura_t" que posso ter. Neste exemplo eu apresentei apenas 2 vetores instanciados em "item_tab", mas posso ter vários vetores, cada um contendo várias entradas do tipo "estrutura_t". Por isso que, ao pegar o ponteiro de um vetor (variavel "item"), quero criar um espelho neste momento apenas do vetor apontado por "item", liberando da memória o espelho anterior antes de alocar um novo espelho

Link para o comentário
Compartilhar em outros sites

Talvez pudesse postar uma especificação do que está tentando fazer.

 

Não vou repetir o que escrevi há pouco, mas do modo como está fazendo não está bom, pelas razões que eu listei e outras. 

 

Um lado importante que (acho que) precisa melhorar é o modelo e a nomenclatura. chamar uma estrutura de "estrutura_t" não é assim um avanço.

item_t, uma estrutura com uma variável char dummy, dúzias de globais, tudo isso vai compor para criar uma coisa muito difícil de gerenciar.

 

Quais os tipos de sensores? De onde vem as strings na estrutura? Eles gravam sozinhos em memória compartilhada? Não mandam um pulso, um registro, nada? Tem um sincronismo?  Como protege a memória? Nunca vi algo assim.

 

4 horas atrás, _FBO_ disse:

que tiveram seus valores modificados, seja por propria entrada do usuario ou seja por atualização proveniente de outras partes do programa

 

Mas é o mesmo programa? Faz diferença de onde veio a alteração? Se quer controlar o display não pode usar um commit bit e criar uma lista dos índices das mudanças conforme vão acontecendo? E usar um loop de eventos onde verifica as coisas e atualiza onde preciso, a la javascript?

 

 

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Certo vou tentar explicar melhor o que estou tentando fazer: ter um código generico, que eu possa reutilizar em varios programas, pra fazer interface de acesso a leitura/edição de variaveis. Pra isso eu gero vetores de uma estrutura para categorizar um grupo de variaveis.

Vou apresentar um exemplo: um sistema que faz o controle de uma impressora 3D. Este sistema possui parametros de ajustes genericos como velocidade de execução, temperatura da mesa e da extrusora e parametros de cada motor. Para categorizar esses parametros utilizando meu codigo seria algo como:

typedef struct{
  char *descricao;
  void *variavel;
  char tipo;
}params_t;

//tela de parametros genericos (veja obsevacao ao termino da definição do vetor "Params0")
params_t Params0[]={
  {"Tempo restante (seg)", &tempo_restante, FLOAT},
  {"Velocidade de execucao (mm/min)", &feed_rate, FLOAT},
  {"Temperatura da mesa (graus)", &temper_mesa, FLOAT},
  {"Temperatura da extrusora (graus)", &temper_extrusora, FLOAT},
  {NULL,NULL,NULL}
};
//osb: o campo "Tempo restante (seg)" é atualizado automaticamente em outro trecho do programa, permitindo que o usuario fique monitorando seu valor enquanto permanece com o vetor "Params0" carregado como sendo o vetor em uso. Os demais campos servem como edição para configurar o comportamento da maquina.

//parametros do eixo X
params_t Params1[]{
  {"Posicao atual (mm)", &medida_x, FLOAT},
  {"Ajuste de medida", &steps_per_mm_x, FLOAT},
  {"Velocidade maxima (mm/min)", &max_speed_x, UINT},
  {"Limite eletrônico (mm)", &lim_x, UINT},
  {NULL,NULL,NULL}
};
//osb: o campo "Posicao atual (mm)" é atualizado automaticamente em outro trecho do programa, permitindo que o usuario fique monitorando seu valor enquanto permanece com o vetor "Params1" carregado como sendo o vetor em uso. Os demais campos servem como edição para configurar o comportamento da maquina.

//parametros do eixo Y
params_t Params2[]{
  {"Posicao atual (mm)", &medida_y, FLOAT},
  {"Ajuste de medida", &steps_per_mm_y, FLOAT},
  {"Velocidade maxima (mm/min)", &max_speed_y, UINT},
  {"Limite eletrônico (mm)", &lim_y, UINT},
  {NULL,NULL,NULL}
};
//osb: o campo "Posicao atual (mm)" é atualizado automaticamente em outro trecho do programa, permitindo que o usuario fique monitorando seu valor enquanto permanece com o vetor "Params2" carregado como sendo o vetor em uso. Os demais campos servem como edição para configurar o comportamento da maquina.

 

Veja que tenho campos utilizados para leitura, que podem ser atualizados a qualquer momento em outros trechos do programa, que devem ser apresentados constantemente para o usuario e tenho também campos que somente são alterados por entrada de valor do usuário, não necessitando ser apresentado constantemente. Com isso eu daria um refresh na apresentação de todo o conteudo do vetor em uso apenas quando o usuario selecionar qual o vetor quer colocar em uso e daria refresh constantemente apenas do conteúdo que foi alterado. Aí que entra o "truque" que quero implementar: ter um espelho do vetor em uso para que eu possa comparar e ver quais os campos que foram alterados para fazer o refresh seletivo, a fim de poupar tempo de execução. Seria algo como essa sequencia:

 

1. espera usuario selecionar um vetor de parametros para visualizar/editar

2. apresenta o conteúdo do vetor selecionado (seja num display, via comunicação serial, etc)

3. carrega o conteúdo do vetor selecionado para um vetor espelho (alocação dinâmica)

4. monitora quais valores do vetor selecionado apresentam diferença em relação aos valores do vetor espelho (faz um "for" comparando os valores do vetor selecionado com o vetor espelho).

5. atualiza para o usuario os campos que sofreram alteração, seja num display, via comunicação serial, etc)

6. carrega o valor do campo alterado no vetor selecionado para o valor correspondente no vetor espelho para novas comparações durante o monitoramento

7. repete passos 4 a 6 enquanto o usuario não selecionar outro vetor diferente.

 

Note que o conteúdo dos vetores de parametros podem ter campos com diferentes informações de texto, diferentes variaveis relacionadas e de diferentes tipos.

Com este código posso facilmente acrescentar/remover novos parametros e assim reutilizar este código em outras aplicações que seguem o mesmo modelo de categorias de parametros

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Solução
Citação

 

 tentar explicar melhor o que estou tentando fazer: ter um código generico, que eu possa reutilizar em varios programas, pra fazer interface de acesso a leitura/edição de variaveis. Pra isso eu gero vetores de uma estrutura para categorizar um grupo de variaveis.

Vou apresentar um exemplo: um sistema que faz o controle de uma impressora 3D. Este sistema possui parametros de ajustes genericos como velocidade de execução, temperatura da mesa e da extrusora e parametros de cada motor.

 

 

Seu exemplo e descrição são quase a mesma coisa que você tinha escrito antes e não fui capaz de entender nada além do que antes. Eu imaginava algo mais formal. Minha falha.
 

Vou tentar te explicar com um outro exemplo

 

typedef struct{
  char *descricao;
  void *variavel;
  char tipo;
}params_t;

params_t Params0[]={
  {"Tempo restante (seg)", &tempo_restante, FLOAT},
  {"Velocidade de execucao (mm/min)", &feed_rate, FLOAT},
  {"Temperatura da mesa (graus)", &temper_mesa, FLOAT},
  {"Temperatura da extrusora (graus)", &temper_extrusora, FLOAT},
  {NULL,NULL,NULL}
};


 

Isso está em seu código. params_t não é assim um nome expressivo e depois declarar Params0 e  Params1 como vetores desse tal tipo não ajuda muito também. E note que se `tipo` é `char` não deve usar a última linha como está. `NULL` é `void*` e o compilador vai claro reclamar como você deve ter notado.

 

Se quer um vetor null-terminated basta usar um único NULL

 

params_t Params0[]={
  {"Tempo restante (seg)", &tempo_restante, FLOAT},
  {"Velocidade de execucao (mm/min)", &feed_rate, FLOAT},
  {"Temperatura da mesa (graus)", &temper_mesa, FLOAT},
  {"Temperatura da extrusora (graus)", &temper_extrusora, FLOAT},
  {NULL}
};

 

Em relação à estrutura em si considere que    

 

typedef struct
{
  char *descricao;
  void *variavel;
  char tipo;
} params_t;
  •    Em `C` você declara um nome associando o mesmo a um tipo. No código fonte os espaços são irrelevantes para o compilador. Mas para o leitor entenda que
    • `descricao` é do tipo `char*`
    • `variavel` é do tipo `void*`
    • `tipo` é `char`

  o asterisco faz parte do tipo e não do nome. é claro que se `descricao` é `char*` então `*descricao` é `char`. É consequência. É a definição em C, mas não é o que está declarando: está declarando o nome.

  •  Provavelmente pode abrir mão do tipo e usar uma parte da descrição, como a primeira letra, já que pelo visto nesse caso tinha apenas `float`, `unsigned long` e `unsigned int`. Pode usar os mesmos valores dos `#define` no primeiro byte da descrição por exemplo
  • Quando ao lado genérico disso, `void*` e `char*` são a expressão do genérico em `C`

 

Container em C
    

Seja lá o que quer representar parece ser um simples container de estruturas, e deve separar o container do conteúdo. E aí pode usar um array, como fez, uma lista ligada, um mapa, uma pilha, qualquer coisa.
Como vai ter um processamento disso talvez uma implementação de lista fosse bem conveniente porque resolveria as duas coisas: podia usar uma lista de `params_t` para compor uma tarefa e uma fila (lista) para representar os eventos.

 

Um exemplo de uma hierarquia simples
 

Partindo da tal `params_t` como a unidade genérica de trabalho uma abstração simples seria considerar que o programa tem uma Missao composta por  Tarefas que são simples listas de Item. Assim poderia mesmo usar um item, como um sensor, em mais de uma tarefa, monitorando uma família de sensores como unidade e usando os smesmos ensores em outras tarefas.

Para poder cria um log das alterações e reconstruir os dados em caso do programa cancelar podia ter um arquivo de log.
 

typedef struct
{
    char id_[4];
    clock_t ts; 
    char* descr;// 0 1 3 para uint ulong float 
    void* val;
}   Item;

typedef struct
{
    char    id_[4];
    clock_t ts;
    char*   descr;
    size_t size;
    Item*  item;
}   Tarefa;

typedef struct
{
    char     id_[4];
    clock_t  ts;
    char*    descr;
    size_t size;
    Tarefa*  t;
}   Missao;


`_id` facilita a pesquisa pelas coisas, e `ts` é a hora do evento. Bem conveniente já que a hora da última atualização sendo conhecida é o que basta para saber por exemplo o que atualizar num painel ou *dashboard*.
 

Citação


@_FBO_ que podem ser atualizados a qualquer momento em outros trechos do programa, que devem ser apresentados constantemente para o usuario e tenho também campos que somente são alterados por entrada de valor do usuário

 


O programa é single-thread, roda um único segmento de código. E toda a estrutura é interna ao programa e não parece haver mecanismo de por exemplo algum sensor gravar direto na memória sem o programa "saber". Assim não parece ter razão para espelhar nada. Bastaria saber o que aconteceu depois da última atualização. E sendo single-thread precisa ser repensado para não parar por exemplo na interface de usuário esperando por alguma alteração de descrição.

 

Um arquivo de log permitira voltar no tempo reconstruindo as estruturas e um esquema simples de serialização traria de volta as estruturas do disco e levaria de volta no final

Um event loop é o caminho comum.

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

@_FBO_ Como eu disse, acho que se tiver uma implementação normal de lista ligada pode simplificar as coisas para esse programa. Pode usar uma lista para conter os "itens" outra para conter os conjuntos de "tarefas" e outra para a fila de eventos a criar. E na fila coloca os eventos vindos do menu (usuário) e do sistema em si --- sensores? --- com a passagem do tempo.

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!