Minha abordagem. O núcleo é o motor. - página 85

 

Falando de intuição. Quero lhes dar um exemplo interessante. Meu post, impresso neste tópico https://www.mql5.com/ru/forum/95632/page12há mais de dois anos:

Реter Konow:

1. O conceito de um motor gráfico.

2. Conceito do núcleo gráfico.

3. estágios de criação do estúdio visual para a plataforma MT.

4. descrição do mecanismo de criação da interface EA.


Omotor gráfico é um programa projetado como um indicador. Este programa é projetado exclusivamente para a gestão da interface do usuário. Ele executa um conjunto de funções básicas:

  • Carregando o núcleo da interface gráfica a partir de um arquivo.
  • Salvando as configurações personalizadas da interface.
  • Implementação do controle unificado e coordenado de todos os processos na interface. Ele implementa a interface "mecânica" incluindo: abrir e fechar janelas, redimensionar janelas, mover janelas, fundir janelas, escalar, jogar scripts, mudar estados de objetos, ligar objetos, controlar valores de parâmetros de controles de acordo com seus tipos e propriedades, criar e destruir variáveis globais.

O motor gráfico é adicionado a um gráfico como qualquer outro indicador . Ela inclui o seguinte conjunto de janelas:

  • Uma barra de tarefas, no lado direito da qual vários ícones serão adicionados para chamar as janelas deserviço do próprio motor.
  • Um navegador de arquivos que será usado para selecionar o arquivo de inicialização deuma lista de arquivos com interfaces localizadas em uma pasta especial.
  • Janelas de ajustes opcionais, que não desempenham um papel crucial nesta fase.

Isto, em princípio, é o fim do conceito do motor gráfico. O importante é que sem ela a operação da interface é impossível.



Um mecanismo gráfico é um bloco de informações contendo dados de todos os objetos e janelas em uma interface, que é registrado em uma matriz e salvo em um arquivo.

Este bloco é uma representação digital da interface gráfica. Ele é carregado pelo motor gráfico a pedido do usuário. O próprio motor gráfico tem seu próprio kernel gráfico interno que assegura o funcionamento de suas próprias janelas, e espaço livre é fornecido dentro deste kernel para a integração da interface do usuário (na forma digital) com ele. A integração é realizada no processo de carregamento do núcleo gráfico a partir de um arquivo.


3. A criação de um estúdio visual na plataforma MT, como eu a entendo, está dividida em duas etapas:

  • Na primeira etapa, será criada uma versão baseada em arquivos do construtor da interface. Nele, o usuário trabalhará com os modelos de mesa. Nas tabelas, o usuário escreverá os tipos e nomes dos elementos de interface e definirá as propriedades de seus parâmetros. A criação será extremamente fácil para o usuário, ele não terá que se preocupar com o posicionamento correto de seus elementos nas janelas (o motor calculará tudo automaticamente) e será suficiente apenas para organizar os elementos na ordem necessária.
  • Na segunda fase, será criado um ambiente visual que implementa o mesmo método de construção de interface que o construtor de arquivos, só que será mais fácil e mais conveniente de usar. Também acrescentará a capacidade de mudar a aparência dos controles. Em geral, o usuário terá mais opções gráficas.


4. Gostaria de delinear o mecanismo do processo de criação da interface e levantar um pouco o véu sobre sua tecnologia. Explique de onde vem a facilidade de criar uma interface através de um arquivo.

Este é o caso: o motor tem uma função especial que cria um kernel gráfico completo baseado em um único arquivo com uma quantidade mínima de informações de carga. As informações de inicialização neste arquivo são auto-explicativas e legíveis por humanos. É fácil de escrever e editar. Por exemplo, você precisa escrever "_CREATE_NEW_WINDOW" para criar uma janela, e "_CHECKBOX" e nome da caixa de seleção, (motor reconhece automaticamente o nome do elemento, como nome do próprio elemento e como nome de seu parâmetro).

Esta função é chamada de "G_CORE_BUILDER()" e constrói o núcleo gráfico tomando dados de duas fontes principais: um arquivo boot-up criado pelo usuário e a matriz "CONTENT[] " contendo todos os grupos padrão de objetos incluídos nas plataformas Windows e de controles. O "CONTEÚDO[] " também contém estados e scripts de objetos. Tudo em uma só matriz. Em geral, o material fonte do "CONTENT[]" + o arquivo carregador criado pelo usuário é usado por "G_CORE_BUILDER()" para construir o núcleo gráfico com o qual o motor trabalha.

Приход нового поколения торговых программ. Каким должен стать интерфейс советников?
Приход нового поколения торговых программ. Каким должен стать интерфейс советников?
  • 2016.09.19
  • www.mql5.com
Уважаемые разработчики, в преддверии скачка развития торговых программ, ожидается что создаваемые нами роботы преобретут массу новых возможностей...
 

É incrível o quanto os termos e conceitos NÃO mudaram em dois anos de trabalho árduo. E as funções e arrays e palavras-chave são como se diz aqui. Tudo foi implementado de acordo com este cenário. E esta tecnologia está funcionando e evoluindo, apesar dofato de que há dois anos atrás eu NÃO tinha nenhuma experiência no desenvolvimento de uma linguagem de marcação.

Não cheguei a um beco sem saída, não mudei o conceito, não mudei a direção. Continuei a criar o motor, o núcleo e a linguagem de marcação exatamente como eu pretendia inicialmente. E a prática confirma que o caminho que escolhi foi o certo.

Se isto não é intuição profética, então o que é?

 

Caros oponentes.

Aqui está o código do roteiro que:

  1. Mede o tempo de transferência de uma string para uma matriz Char, para passar a string para outro programa através de um recurso e o tempo de recuperação de uma string de uma matriz Char para posterior divisão e recuperação de informações.
  2. Mede o tempo para escrever a string na descrição do objeto MT e o tempo para recuperar a string da descrição do objeto MT, para posterior divisão e recuperação de informações.
//+------------------------------------------------------------------+
//|                        CharArrayToString и StringToCharArray.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
//--------------------------------------------

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   string qwerty = "qierfhqoerifhqoiwerufhqoiwerfhwioefhqowasdkfj";   
   uchar Arr[];
   //---------------------------------
   //Создаем объект связи.
   //---------------------------------
   ObjectCreate(0,"button_1",OBJ_BUTTON,0,0,0);   
   //---------------------------------
   ulong t1 = GetMicrosecondCount();
   //---------------------------------
   //Переводим строку в тип Char
   //---------------------------------
   StringToCharArray(qwerty,Arr,0,WHOLE_ARRAY);
   //---------------------------------
   ulong t2 = GetMicrosecondCount();
   //---------------------------------
   //Переводим массив Char обратно в строку:
   //---------------------------------
   string str_1 = CharArrayToString(Arr,0,WHOLE_ARRAY);
   //---------------------------------
   ulong t3 = GetMicrosecondCount();
   //---------------------------------
   //Записываем строку в описании МТ-объекта.
   //---------------------------------
   ObjectSetString(0,"button_1",OBJPROP_TEXT,"qierfhqoerifhqoiwerufhqoiwerfhwioefhqowasdkfj");
   ulong t4 = GetMicrosecondCount();
   //---------------------------------
   //Cчитываем строку из описания МТ-объекта.
   //---------------------------------
   string str_2 = ObjectGetString(0,"button_1",OBJPROP_TEXT);
   ulong t5 = GetMicrosecondCount();
   //---------------------------------   
   //Замеряем время исполнения.
   //----------------------------------------------
   Print("Time of execution StringToCharArray:   ",t2-t1);
   Print("Time of execution CharArrayToString:   ",t3-t2," строка от CharArrayToString:  ",str_1);
   //----------------------------------------------
   Print("Time of execution ObjectSetString:     ",t4-t3);
   Print("Time of execution ObjectGetString:     ",t5-t4," строка от ObjectGetString:  ",str_2);
   //----------------------------------------------
  }
//+------------------------------------------------------------------+

Resultado:

2018.12.18 16:44:20.042 CharArrayToString и StringToCharArray GBPUSD,M5: Time of execution StringToCharArray:   47
2018.12.18 16:44:20.042 CharArrayToString и StringToCharArray GBPUSD,M5: Time of execution CharArrayToString:   35 строка от CharArrayToString:  qierfhqoerifhqoiwerufhqoiwerfhwioefhqowasdkfj

2018.12.18 16:44:20.042 CharArrayToString и StringToCharArray GBPUSD,M5: Time of execution ObjectSetString:     3
2018.12.18 16:44:20.042 CharArrayToString и StringToCharArray GBPUSD,M5: Time of execution ObjectGetString:     3 строка от ObjectGetString:  qierfhqoerifhqoiwerufhqoiwerfhwioefhqowasdkfj


 

Minha solução é mais de 10 vezes mais rápida.

Adicione à sua solução, o tempo para economizar o recurso e o tempo para colocar o recurso na matriz usando ResourceReadImage();

Na minha solução, nem a primeira nem a segunda são necessárias.

 
Реter Konow:
Minha solução é mais de 10 vezes mais rápida.

Peter, se você trabalhar com cordel, perderá o desempenho em qualquer caso. Portanto, é surpreendente ouvir você perseguir um desempenho mítico, mesmo que originalmente você tenha escolhido uma solução inadequada para ele: passar mensagens através de um fio e depois analisar essa mensagem.

 
Vasiliy Sokolov:

Peter, se você trabalhar com cordel, perderá o desempenho em qualquer caso. Portanto, é surpreendente ouvir você perseguir um desempenho mítico, mesmo tendo escolhido originalmente uma solução inadequada para ele: passar mensagens através de um fio e depois analisar essa mensagem.

Vasily, de que outra forma você transfere dados de todos os tipos entre programas?

OnChartEvent() é parcialmente adequado.

  1. Não funciona no testador.
  2. Com um grande número de chamadas - a fila do evento fica entupida.


 
E, a propósito, medidas inferiores a 20 milissegundos não são, a rigor, válidas, pelo menos em sistemas multithreading preventivos. Mas mesmo que você aceite seu resultado (em geral eu o admito), ele ainda não lhe diz nada, porque o que importa são os custos do círculo completo. E o que você mediu é apenas parte dele.
 
Vasiliy Sokolov:
E a propósito, medindo menos de 20 milissegundos, estritamente falando não é válido, pelo menos em sistemas com multithreading preemptivo. Mas mesmo que você aceite seu resultado (em geral eu o admito), ele ainda não lhe diz nada, porque o que importa são os custos do círculo completo. E o que você mediu é apenas parte dele.

Preciso de um caminho universal e o mais rápido. Para trabalhar no testador e contornar a fila de eventos OnChartEvent();

O teste mostra que a transferência através dos recursos é 10 vezes mais lenta. (sem medir o tempo para economizar recursos e obter dados a partir delesusando ResourceReadImage()) .

Minha solução é a melhor opção em condições iniciais.

 
Vasiliy Sokolov:
...Mas mesmo que você aceite seu resultado (em geral eu o admito), ele ainda não lhe diz nada, porque o que importa são os custos do círculo completo. E o que você mediu é apenas parte dele.

É verdade, mas se você extrapolar para mais linhas e engrenagens, minha opção ainda ganha.

 
Реter Konow:

Vasiliy, de que outra forma você transfere dados de todos os tipos entre programas?

Mapeamento direto de estruturas através de matriz de bytes sindicalizados, compartilhados para acesso global. Não sei se isto é tecnicamente viável, mas se assim for, a velocidade será cósmica, pois não será preciso copiar nada.