Padrão “Instantâneo”

Neste post irei descrever o padrão “Snapshot” ou “Memento”

Este padrão refere-se a padrões “Comportamentais” padrões de design.

Suponha que estamos desenvolvendo um editor gráfico e precisamos adicionar a capacidade de reverter ações mediante um comando do usuário. Também é muito importante que os componentes do sistema não tenham acesso ao estado interno das “ações” seu estado interno, fornecendo uma interface externa clara e simples. Para resolver este problema, o padrão “Snapshot” ou “Guardião”.

Exemplo de trabalho “Instantâneo” apresentado abaixo:


Ao clicar, um sprite aparece, ao clicar na seta enrolada, a ação é cancelada – O sprite desaparece. O exemplo consiste em três classes:

  1. Tela na qual os sprites e a interface gráfica são exibidos.
  2. Controlador de tela, processa cliques e controla a lógica da tela.
  3. Os estados da tela que persistem a cada alteração são revertidos, se necessário, usando o controlador de tela.

No contexto do padrão “Snapshot” as aulas são:

  1. Tela – fonte, os estados desta classe são salvos como “instantâneos”, para reversão posterior mediante solicitação. Além disso, a fonte deve ser capaz de restaurar o estado ao transferir um “instantâneo”
  2. Controlador – custodiante, esta classe sabe como e quando salvar/reverter estados.
  3. Estado – snapshot, uma classe que armazena o estado da origem, além de informações de data ou um índice a partir do qual a ordem de reversão pode ser estabelecida com precisão.

Uma característica importante do padrão é que apenas a fonte deve ter acesso aos campos internos do estado salvo no instantâneo. Isso é necessário para proteger os instantâneos de alterações externas (de desenvolvedores úteis que desejam alterar algo ignorando o encapsulamento; , quebrando a lógica do sistema). Para implementar o encapsulamento, são usadas classes integradas e, em C++, elas usam a capacidade de especificar classes amigas. Pessoalmente, implementei uma versão simples sem encapsulamento para Rise e usando Generic ao implementar para Swift. Na minha versão – Memento fornece seu estado interno apenas para entidades do mesmo estado de classe:

Fontes

https://refactoring.guru/design-patterns/memento

Código fonte

https://gitlab.com/demensdeum/patterns/< /p>

Padrão de visitante

Neste post irei descrever um padrão de design chamado “Visitante” ou “Visitante”
Este padrão pertence ao grupo de Padrões de comportamento.

Vamos encontrar um problema

Esse padrão é usado principalmente para contornar a limitação do envio único em linguagens de ligação antecipada.

Alice X por NFGPhoto (CC-2.0)
Vamos criar uma classe/protocolo abstrato Band, fazer uma subclasse de MurpleDeep, criar uma classe Visitor com dois métodos – um para enviar qualquer descendente de Band para o console, o segundo para gerar qualquer MurpleDeep, o principal é que os nomes (assinaturas) dos métodos sejam os mesmos e os argumentos diferem apenas por classe. Usando o método de impressão intermediário com o argumento Band, criamos uma instância de Visitor e chamamos o método visit para MurpleDeep.
Abaixo está o código em Kotlin:

A saída será “Esta é a classe Band

Como isso é possível?!

Por que isso acontece é descrito em palavras inteligentes em muitos artigos, inclusive em russo, mas sugiro que você imagine como o compilador vê o código, talvez tudo fique claro imediatamente:

Resolvendo o problema

Existem muitas soluções para resolver este problema, a seguir consideraremos uma solução usando o padrão Visitor.
Adicionamos o método Accept com o argumento Visitor à classe/protocolo abstrato, chamamos Visitor.visit(this) dentro do método e, em seguida, adicionamos uma substituição/implementação do método Accept à classe MurpleDeep, violando DRY de forma decisiva e calma, novamente escrevendo visitante.visita(este).< br />Código final:

Fontes

https://refactoring.guru/ru/ padrões de design/visitor-double-dispatch

Código fonte

https://gitlab.com/demensdeum/patterns

Padrão peso mosca

Neste post irei descrever o padrão estrutural “Leve” ou “Oportunista” (Peso mosca)
Este padrão pertence ao grupo de Padrões Estruturais.

Vejamos abaixo um exemplo de como o padrão funciona:


Por que é necessário? Para economizar RAM. Concordo que em tempos de uso generalizado do Java (que consome CPU e memória à toa), isso não é mais tão importante, mas vale a pena usar.
No exemplo acima, apenas 40 objetos são gerados, mas se você aumentar o número para 120.000, o consumo de memória aumentará proporcionalmente.
Vejamos o consumo de memória sem usar o padrão flyweight no navegador Chromium:

Sem usar um padrão, o consumo de memória é de aproximadamente 300 megabytes.

Agora vamos adicionar um padrão ao aplicativo e ver o consumo de memória:

Usando o padrão, o consumo de memória é de aproximadamente 200 megabytes, então economizamos 100 megabytes de memória no aplicativo de teste; em projetos sérios, a diferença pode ser muito maior.

Como funciona?

No exemplo acima, desenhamos 40 gatos, ou para maior clareza, 120 mil. Cada gato é carregado na memória como uma imagem png e, na maioria das renderizações, ele é convertido em um bitmap para renderização (na verdade, bmp), isso é feito para aumentar a velocidade, já que um png compactado leva muito tempo para ser renderizado. Sem usar o padrão, carregamos 120 mil fotos de gatos na RAM e desenhamos, mas ao usar o padrão “leve” carregamos um gato na memória e desenhamos 120 mil vezes com diferentes posições e transparência. A mágica é que implementamos coordenadas e transparência separadamente da imagem do gato durante a renderização, a renderização pega apenas um gato e usa um objeto com coordenadas e transparência para a renderização correta.

Como é isso no código?

A seguir estão exemplos da linguagem Rise

Sem usar um padrão:


A imagem do gato é carregada separadamente para cada objeto no loop – catImage.

Usando padrão:

Uma imagem de um gato é usada por 120 mil objetos.

Onde é usado?

Usado em estruturas GUI, por exemplo, o “reuse” (reutilizar) células da tabela UITableViewCell, o que aumenta a barreira de entrada para iniciantes que não conhecem esse padrão. Também comumente usado no desenvolvimento de jogos.

Código fonte

https://gitlab.com/demensdeum/patterns/< /p>

Fontes

https://refactoring.guru/ru/design-patterns/ peso mosca
http://gameprogrammingpatterns.com/flyweight.html

O bom, o mau e o feio Singleton

Nesta nota descreverei minha experiência e a experiência de meus colegas ao trabalhar com o padrão Singleton (Singleton na literatura estrangeira), enquanto trabalhava em vários projetos (bem-sucedidos e não tão bem-sucedidos). Descreverei por que pessoalmente acho que esse padrão não pode ser usado em lugar nenhum e também descreverei quais fatores psicológicos na equipe influenciam a integração desse antipadrão. Dedicado a todos os desenvolvedores caídos e aleijados que estavam tentando entender por que tudo começou com um dos membros da equipe trazendo um cachorrinho fofo, fácil de manusear, que não requer cuidados e conhecimentos especiais para cuidar dele, e terminou com a fera criada tomar seu projeto como refém, requer cada vez mais horas de trabalho e consome os nervos do usuário, seu dinheiro e cria números absolutamente monstruosos para avaliar a implementação de coisas aparentemente simples coisas.


Wolf in sheep’s clothing by SarahRichterArt

A história se passa em um universo alternativo, todas as coincidências são aleatórias…

Acaricie o gato em casa com Cat@Home

Toda pessoa às vezes na vida tem um desejo irresistível de acariciar um gato. Analistas de todo o mundo prevêem que a primeira startup que criou um aplicativo para entrega e aluguel de gatos se tornará extremamente popular e em um futuro próximo será comprada pelo Moogle por trilhões de dólares. Logo isso acontece – um cara de Tyumen cria o aplicativo Cat@Home e logo se torna um trilionário, a empresa Moogle obtém uma nova fonte de lucro e milhões de pessoas estressadas têm a oportunidade de peça um gato para sua casa para passar mais roupas e se acalmar.

Ataque dos Clones

Um dentista extremamente rico de Murmansk, Alexey Goloborodko, impressionado com um artigo sobre Cat@Home da Forbes, decide que também quer ser astronomicamente rico. Para atingir esse objetivo, através de seus amigos, ele encontra uma empresa de Goldfield – que é a cidade de Goldfield. Wakeboard DevPops, que fornece serviços de desenvolvimento de software, encomenda a eles o desenvolvimento de um clone Cat@Home.

Time vencedor

O projeto se chama Fur&Pure, confiado a uma talentosa equipe de desenvolvimento de 20 pessoas; A seguir, vamos nos concentrar em uma equipe de desenvolvimento móvel de 5 pessoas. Cada membro da equipe recebe sua parte do trabalho, munido de ágil e scrum, a equipe conclui o desenvolvimento no prazo (em seis meses), sem bugs, lança o aplicativo na iStore, onde é avaliado em 5 por 100.000 usuários, há muitos comentários sobre o quão bom é o aplicativo, quão excelente é o serviço (afinal, universo alternativo). Os gatos estão passados, o aplicativo está liberado, tudo parece estar indo bem. Porém, Moogle não tem pressa em comprar uma startup por trilhões de dólares, porque não só gatos, mas também cachorros já apareceram no Cat@Home.

O cachorro late, a caravana segue em frente

O proprietário do aplicativo decide que é hora de adicionar cães ao aplicativo, solicita uma avaliação à empresa e recebe aproximadamente pelo menos seis meses para adicionar cães ao aplicativo. Na verdade, o aplicativo será escrito do zero novamente. Durante esse período, o Moogle adicionará cobras, aranhas e porquinhos-da-índia ao aplicativo, e o Fur&Pur receberá apenas cães.
Por que isso aconteceu? A falta de arquitetura de aplicação flexível é a culpada por tudo; um dos fatores mais comuns é o antipadrão Singleton.

O que há de errado?

Para encomendar um gato em casa o consumidor precisa criar um pedido e encaminhá-lo para o escritório, onde o escritório irá processá-lo e enviar um entregador com o gato, o entregador já receberá o pagamento pelo serviço.
Um dos programadores decide criar uma classe “Cat Application” com os campos necessários, traz esta classe para o espaço global da aplicação através de um singleton. Por que ele está fazendo isso? Para economizar tempo (economizando meia hora), porque é mais fácil tornar um aplicativo público do que pensar na arquitetura do aplicativo e usar injeção de dependência. Então outros desenvolvedores pegam esse objeto global e vinculam suas classes a ele.
Por exemplo, todas as telas acessam o objeto global “Cat Request” e mostrar dados do aplicativo. Como resultado, esse aplicativo monolítico é testado e lançado.
Tudo parece estar bem, mas de repente aparece um cliente com a necessidade de adicionar solicitações de cães ao aplicativo. A equipe começa a avaliar freneticamente quantos componentes do sistema serão afetados por essa mudança. Ao final da análise, verifica-se que é necessário refazer de 60 a 90% do código para ensinar a aplicação a aceitar não apenas “Request For Cat” mas também “Pedido de Cachorro”, já é inútil avaliar a adição de outros animais nesta fase, para dar conta de pelo menos dois.

Como prevenir o singleton

Primeiro, na fase de levantamento de requisitos, indique explicitamente a necessidade de criar uma arquitetura flexível e extensível. Em segundo lugar, vale a pena realizar uma revisão independente do código do produto paralelamente, com pesquisa obrigatória dos pontos fracos. Se você é um desenvolvedor e adora singletons, sugiro que recupere o juízo antes que seja tarde demais, caso contrário, noites sem dormir e nervos em frangalhos serão garantidos. Se você estiver trabalhando em um projeto legado que possui muitos singletons, tente se livrar deles ou do projeto o mais rápido possível.
Você precisa mudar do antipadrão de objetos/variáveis ​​globais singletons para injeção de dependência – o padrão de design mais simples no qual todos os dados necessários são fornecidos a uma instância de uma classe no estágio de inicialização, sem necessidade adicional de serem vinculados ao espaço global.

Fontes

https://stackoverflow. com/questions/137975/what-is-so-bad-about-singletons
http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/
https://blog.ndepend.com/singleton-pattern-costs/

Relatório de desenvolvimento da Máscara da Morte 1

Nova seção não permanente “diários do desenvolvedor” ou Diário do Desenvolvedor em estilo estrangeiro.
O desenvolvimento do jogo Death-Mask está a todo vapor, o logotipo do motor foi adicionado para os jogos Flame Steel Engine 2019, tela para seleção do mapa inicial por ilha (verde, vermelho, preto, branco), saída de texturas para paredes, teto, piso do labirinto, aumento do tamanho da área de jogo.


Mapa da Cidade da Zona Vermelha

Em seguida, planejamos adicionar modelos 3D para o ambiente, em vez de sprites estilo Doom, e planejamos adicionar modelos para armas, caixas, inimigos e amigos. Na jogabilidade está prevista a adição de moeda, lojas, a possibilidade de comprar partes do mapa do jogo indicando locais interessantes com saques e a possível localização da “Máscara da Morte”. Também quero adicionar a possibilidade de contratar companheiros para viajar pelo labirinto cibernético.
Acompanhe as novidades.

Rápido 4.2.3 – Ubuntu 18.10

Construindo o Swift com as bibliotecas necessárias para rodar no Ubuntu 18.10. Versão mais recente disponível no site da Apple – para Ubuntu 18.04. Baseado na montagem do site oficial com adição de bibliotecas do Ubuntu 18.04. Também foi adicionado um script de exemplo para adicionar PATH e LD_LIBRARY_PATH ao terminal bash:
http://www.mediafire.com/file/lrs74mvoj3fti03/swift4.2.3.ubuntu.18.10.x86_64.tar.gz/file

Linguagem declarativa Zakaz

Apresento a sua atenção uma linguagem de programação declarativa pura – Zakaz. A ideia principal da nova linguagem – a aplicação contém comandos de execução escritos em formato livre que devem ser executados pelos “executores”. Se nenhum “artista” não puder executar o comando, a execução do programa será interrompida. As aplicações são chamadas de especificações técnicas (tez) e devem ter extensão .tez. A sintaxe Zakaz requer duas regras:

  • Cada comando começa em uma nova linha
  • Cada comando deve ser escrito em linguagem formal que seja compreensível para os humanos

Exemplo Olá Mundo.tez:

Mostrar texto "Hello World" na telaMostrar "Exemplo de Zakaz 'tez'" na tela

Um exemplo de especificação que exibe uma descrição do princípio de funcionamento e abertura do site http://demensdeum.com no navegador Firefox

Mostrar texto "Mostrar demonstração do site" na telaShow "Você precisa do Firefox instalado em seu sistema para executar este 'tez', e ele deve ser chamado através de \"sistema\" Função C" texto na telaMostrar "Também deve haver \"FirefoxPerformer\" atribuído ao Zakaz Runtime, verifique o manual para mais informações" texto na telaMostrar site com endereço "http://demensdeum.com" no Firefox

Você deve executar o exemplo acima junto com o “executor” FirefoxPerformer, que é capaz de processar o comando mais recente para renderizar um site através do Firefox

./ZakazRuntime openDemensdeumSite.tez FirefoxPerformer

Para implementar seu executor, você precisa implementá-lo como uma biblioteca dinâmica usando a classe abstrata ZakazRuntime::Performer e retorná-lo junto com um ponteiro inteligente do método de função global createPerformer(). Você pode usar a implementação do FirefoxPerformer como exemplo.

Código fonte

https://gitlab.com/demensdeum/zakaz

С++ Application Plugins

In this post I will describe an example of adding functionality to a C ++ application using plugins. The practical part of the implementation for Linux is described; the theory can be found at the links at the end of the article.

Composition over inheritance!

To begin with, we will write a plugin – a function that we will call:

#include "iostream"

using namespace std;

extern "C" void extensionEntryPoint() {
	cout << "Extension entry point called" << endl;
};

Next, we will build the plugin as a dynamic library “extension.so”, which we will connect in the future:
clang++ -shared -fPIC extension.cpp -o extension.so

Next we write the main application that will load the file “extension.so”, look for a pointer to the function “extensionEntryPoint” there, and call it, typing errors if necessary:

#include "iostream"
#include "dlfcn.h"

using namespace std;

typedef void (*VoidFunctionPointer)();	

int main (int argc, char *argv[]) {

	cout << "C++ Plugins Example" << endl;

	auto extensionHandle = dlopen("./extension.so", RTLD_LAZY);
	if (!extensionHandle) {
		string errorString = dlerror();
		throw runtime_error(errorString);
	}

	auto functionPointer = VoidFunctionPointer();
	functionPointer = (VoidFunctionPointer) dlsym(extensionHandle, "extensionEntryPoint");
	auto dlsymError = dlerror();
 	if (dlsymError) {
		string errorString = dlerror();
		throw runtime_error(errorString);
 	}

	functionPointer();

	exit(0);
} 

The dlopen function returns a handler for working with a dynamic library; dlsym function returns a pointer to the required function by string; dlerror contains a pointer to the string with the error text, if any.

Next, build the main application, copy the file of the dynamic library in the folder with it and run. The output should be the “Extension entry point called”

Difficult moments include the lack of a single standard for working with dynamic libraries, because of this there is a need to export the function to a relatively global scope with extern C; the difference in working with different operating systems associated with this subtlety of work; the lack of a C ++ interface to implement OOP approach to working with dynamic libraries, however, there are open-source wrappers, for example m-renaud/libdlibxx

Example Source Code

https://gitlab.com/demensdeum/cpppluginsexample

Documents

http://man7.org/linux/man-pages/man3/dlopen.3.htm
https://gist.github.com/tailriver/30bf0c943325330b7b6a
https://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work

Flutter como Michelle

[Sinta o poder da Inteligência Artificial]
Neste post vou lhe dizer como prever o futuro.

Na estatística existe uma classe de problemas – análise de série temporal. Tendo uma data e o valor de uma determinada variável, você pode prever o valor desta variável no futuro.
Primeiro eu queria implementar uma solução para este problema usando TensorFlow, mas encontrou a biblioteca Profeta por Facebook.
Prophet permite que você faça uma previsão com base em dados (csv) contendo colunas de data (ds) e valor variável (y). Você pode descobrir como trabalhar com ele na documentação do site oficial na seção Início rápido
Como conjunto de dados, usei um upload csv do site https://www.investing.com, ao implementar usei Linguagem R e API do Profeta para ele. Gostei muito do R, pois sua sintaxe simplifica o trabalho com grandes quantidades de dados, permite escrever de forma mais simples e cometer menos erros do que ao trabalhar com linguagens convencionais (Python), já que teria que trabalhar com expressões lambda, e no R você já tem todas as expressões lambda.
Para não preparar os dados para processamento, utilizei o pacote a qualquer momento, que pode converter strings em uma data, sem pré-processamento. A conversão de strings de moeda em números é feita usando o pacote readr

Como resultado, recebi uma previsão segundo a qual o Bitcoin custará US$ 8.400 até o final de 2019 e a taxa de câmbio do dólar será de 61 rublos. Devemos acreditar nessas previsões? Pessoalmente, acho que não vale a pena, porque… Você não pode usar métodos matemáticos sem compreender sua essência.

Fontes

https:// facebook.github.io/prophet
https://habr.com/company/ods/blog/323730/
https://www.r-project.org/

Código fonte

https://gitlab.com/demensdeum/MachineLearning/tree/master/4prophet

Tesla fala

Nesta postagem, descreverei o processo de criação de um gerador de cotações.

TL;DR

Para treinamento e geração de texto – use a biblioteca textgenrnn, para filtrar frases você precisa usar a verificação ortográfica usando o hunspell e suas bibliotecas para C/python. Após o treinamento em Colaboratório, você pode começar a gerar texto. Cerca de 90% do texto será completamente ilegível, no entanto, os 10% restantes conterão um pouco de significado e, com modificação manual, as frases ficarão muito boas.
A maneira mais fácil é lançar uma rede neural pronta no Colaboratory:
https://colab.research.google.com/drive/1-wbZMmxvsm3SoclJv11villo9VbUesbc(abre em uma nova guia)”>https://colab.research.google.com/drive/1-wbZMmxvsm3SoclJv11villo9VbUesbc

Código-fonte

https://gitlab.com/demensdeum/MachineLearning/tree/master/3quotesGenerator

Fontes

https://karpathy.github.io/2015/05/21/rnn-effectiveness/https://medium.com/deep-learning-turkey/google-colab-free-gpu-tutorial-e113627b9f5dhttps://minimaxir.com/2018/05/text-neural-networks/
https://github.com/wooorm/dictionaries (opens in a new tab)” href=”https://minimaxir.com/2018/05/text-neural-networks/” target=”_blank”>https://minimaxir.com/2018/05/text-neural-networks/
https://karpathy.github.io/2015/05/21/rnn-effectiveness/
https://medium.com/deep-learning-turkey/google-colab-free-gpu-tutorial-e113627b9f5d
https://karpathy.github.io/2015/05/21/rnn-effectiveness/ (opens in a new tab)” href=”https://karpathy.github.io/2015/05/21/rnn-effectiveness/” target=”_blank”>https://karpathy.github.io/2015/05/21/rnn-effectiveness/
https://medium.com/deep-learning-turkey/google-colab-free-gpu-tutorial-e113627b9f5d
https://karpathy.github.io/2015/05/21/rnn-effectiveness/https://medium.com/deep-learning-turkey/google-colab-free-gpu-tutorial-e113627b9f5dhttps://github.com/wooorm/dictionaries

” rel=”noopener” target=”_blank”>https://github.com/wooorm/dictionaries (opens in a new tab)”>https://github.com/wooorm/dictionaries

Quantos erros você tem aí?

No Hacker News encontrei um artigo muito interessante no qual o autor sugere o uso do Método Petersen-Lincoln , que é usado por biólogos para contar a população de pássaros, macacos e outros animais, para *rufar de tambores* contar bugs no aplicativo.

Erro em habitat natural – Avistamento do Pé Grande por Derek Hatfield

O método é muito simples, pegamos dois ornitólogos, eles descobrem aves de uma determinada espécie, sua tarefa é – determinar o tamanho da população dessas aves. As aves encontradas são marcadas por ambos os ornitólogos, então o número de aves comuns é calculado, substituído na fórmula do índice de Lincoln e obtemos o tamanho aproximado da população.
Agora, para aplicativos – o método também é muito simples, pegamos dois QAs e eles encontram bugs na aplicação. Digamos que um testador encontrou 10 bugs (E1) e o segundo testador encontrou 20 bugs (E2), agora pegamos o número total de bugs – 3 (S), então usando a fórmula obtemos o índice Lincoln:

Esta é uma previsão do número de bugs em todo o aplicativo. No exemplo dado, há aproximadamente 66 bugs.

Exemplo rápido

Implementei um banco de testes para testar o método, você pode vê-lo aqui:
https://paiza.io/projects/AY_9T3oaN9a-xICAx_H4qw?language=swift

Parâmetros que podem ser alterados:

deixe aliceErrorFindProbability = 20 – porcentagem de bugs encontrados pelo QA Alice (20%)
deixe bobErrorFindProbability = 60 – porcentagem de bugs encontrados pelo QA Bob (60%)
deixe actualBugsCount = 200 – quantos bugs existem realmente no aplicativo

Na última execução recebi os seguintes dados:
Contagem de bugs estimados: 213
Contagem real de bugs: 200

Ou seja, existem 200 bugs no aplicativo, o Índice Lincoln dá uma previsão – 213:
“Alice encontrou 36 bugs”
“Bob encontrou 89 bugs”
“Contagem de bugs comuns: 15”

Contagem de bugs estimados: 213
Contagem real de bugs: 200

Fraquezas

Este método pode ser usado para avaliar o número de erros na aplicação em todos os estágios de desenvolvimento. idealmente, o número de bugs deve diminuir. Os pontos fracos do método incluem o fator humano, uma vez que o número de bugs encontrados por dois testadores deveria ser diferente e bugs diferentes foram encontrados, no entanto os mais comuns devem ser encontrados, caso contrário o método não funcionará (zero bugs comuns – divisão por zero)< br/>Além disso, um conceito como bugs comuns requer a presença de um especialista para entender seus pontos em comum.

Fontes

Quantos erros faltam encontrar? – John D. Cook, PhD, Presidente
The thrill of the chase – Brian Hayes

Código fonte

https://paiza.io/projects/AY_9T3oaN9a-xICAx_H4qw ?idioma=rápido
https://gitlab.com/demensdeum/statistics/tree/master/1_BugsCountEstimation/src

Engrenagens de moagem

Oh musa, como às vezes é difícil te pegar.
O desenvolvimento de Death-Mask e frameworks relacionados (Flame Steel Core, Game Toolkit, etc.) está suspenso por vários meses para decidir sobre a parte artística do jogo, música, som e jogabilidade.
Planos – criar um editor para o Flame Steel Game Toolkit, escrever um intérprete para scripts de jogos (baseado na sintaxe Rise), implementar o jogo Death-Mask para tantas plataformas quanto possível.
A fase mais difícil foi ultrapassada – na prática, foi comprovada a possibilidade de escrever seu próprio motor de jogo multiplataforma, seu próprio IDE e um conjunto de bibliotecas.
Estou passando para a fase de criação de um projeto realmente bem pensado e interessante, fique ligado.

Rastreador de notícias para iOS

Rastreador de notícias para iOS – o aplicativo procura texto e exibe o resultado durante o carregamento.
O suporte para arquivos grandes está incluído imediatamente (> 200 MB), os resultados são salvos no arquivo result.log.
Design simples e atencioso.
Suporte Regex usando a biblioteca Regex.

Código fonte:
https://gitlab.com/demensdeum/news-crawler

Máscara mortuária em domínio público

A partir de hoje, o jogo Death-Mask estará em acesso aberto – Você pode acompanhar o andamento da implementação do jogo no link: (Uau!)
[Máscara da Morte Selvagem]

Versão atual – 0.1 contém controles básicos de seta, wsad, geração de mapas, itens (incluindo a máscara mortuária!), renderização.
Ainda há muito trabalho a ser feito e estou muito interessado no seu feedback. para que você possa escrever comentários na página com a versão selvagem do jogo.
Na versão final, o jogo termina após o jogador encontrar o item – Máscara Mortuária
Bons testes 🙂

Авторы ресурсов

Utilitário de indexação de código-fonte Hangar18

Hangar18 – Utilitário de indexação de código-fonte C++ escrito em Rust. Este utilitário implementará a funcionalidade “ir para definição” no Sabre-Plus IDE.
A entrada para o utilitário é o caminho absoluto para o diretório do código-fonte e a linha de declaração que precisa ser encontrada. A saída é semelhante ao grep.

Código fonte:
https://gitlab.com/demensdeum/hangar18

Taytay monitorando o status dos repositórios Git

Apresento a sua atenção Taytay – um utilitário para monitorar o status dos repositórios git para a linguagem Swift. Atualmente, o Swift pode ser instalado em todos os sistemas operacionais de desktop convencionais. Para Ubuntu, recomendo usar Swiftenv. Vinculou Taytay ao utilitário git-cola, mas você pode editar a fonte e alterá-la para qualquer outro programa.

Código fonte:
https://gitlab.com/demensdeum/taytay

Vencemos Malevich, Black Squares OpenGl

Malevich chega periodicamente a qualquer desenvolvedor no OpenGL. Isso acontece inesperadamente e com ousadia, você apenas inicia o projeto e vê um quadrado preto em vez de uma renderização maravilhosa:

Hoje descreverei por que motivo fui visitado por um quadrado preto, os problemas encontrados por causa dos quais o OpenGL não desenha nada na tela e às vezes até torna a janela transparente.

Use ferramentas

Para depurar o OpenGL, duas ferramentas me ajudaram: renderdoc e Death-Mask O que não mostra nada na tela (apenas um quadrado). Ao usar chroot e montagem em 16.10 i recebo uma assembléia de trabalho do jogo com gráficos .

Parece que algo quebrou no Ubuntu 18.04

ldd mostrou a linkka às bibliotecas idênticas sdl2, gl. Dirigindo uma construção não trabalhadora no RenderDoc, vi lixo na entrada do shader do vértice, mas precisava de uma confirmação mais sólida. Para entender a diferença entre os binarticos, eu os dirigi através do Apitrace . A comparação de lixeiras me mostrou que a assembléia em uma nova ubunta quebra o programa das perspectivas no OpenGL, na verdade enviando lixo lá:

Matrizes se reúnem na biblioteca GLM. Depois de copiar o GLM de 16.04 – Recebi a construção do jogo novamente. O problema foi a diferença na inicialização de uma única matriz no GLM 9.9.0, é necessário indicar claramente o argumento MAT4 (1.0F) nele no construtor. Tendo mudado a inicialização e escrevendo O autor da biblioteca, eu comecei a fazer testes para fsgl . No processo de escrita que encontrei falhas no FSGL, as descrevo ainda mais.

Determine quem está na vida

Para o trabalho correto com o OpenGL, você precisa voluntariamente à força solicitar o contexto de uma determinada versão. Então, ele procura SDL2 (você precisa colocar a versão estritamente antes de inicializar o contexto):


 sdl_gl_seettrtribute (sdl_gl_context_major_version,  3 );
Sdl_gl_settribute (sdl_gl_context_minor_version, 2 );
Sdl_gl_settribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

Por exemplo, o renderDoc não funciona com contextos abaixo de 3.2. Gostaria de observar que, depois de alternar o contexto , há uma alta probabilidade de ver a mesma tela preta . Por que?

Como o contexto do OpenGL 3.2 deve exigir a presença de buffer VAO , sem o qual 99% dos drivers gráficos não funcionam. Adicione fácil:


 glgenvertexarrays ( 1 ,  &  vao);
Glbindvertexaray (VAO);

Não durma, congele

Também encontrei um problema interessante no Kubuntu, em vez de um quadrado preto, fui exibido transparente e, às vezes, tudo era renderizado corretamente. Encontrei a solução para esse problema no Stack Overflow:
https://stackoverflow.com/questions/38411515/sdl2-opengl-window-appears-semi-transparent-sometimes

O código de renderização do teste FSGL também estava presente Sleep (2s) ; Então, no Xubuntu e Ubuntu, recebi a renderização correta e enviei o pedido para dormir, mas no Kubuntu recebi uma tela transparente em 80% do lançamento do golfinho e 30% dos lançamentos e terminais. Para resolver esse problema, adicionei a renderização em cada quadro, após uma pesquisa do SDLEVENT, conforme recomendado na documentação.

Código de teste:
https://gitlab.com/demensdeum/FSGLtests/blob/master/renderModelTest/

Fale com o motorista

OpenGL suporta o canal de comunicação entre o aplicativo e o driver, para ativá-lo, você precisa ativar os sinalizadores GL_DEBUG_OUTPUT, GL_DEBUG_OUTPUT_SYNCHRONUS, Afixar o aviso GLDebugMessagEntrol e tie the callback através de .
Um exemplo de inicialização pode ser tomado aqui:
https://github.com/rock-core/gui-vizkit3d/blob/master/src/EnableGLDebugOperation.cpp

Não tenha medo, veja crescer

Neste post falarei sobre minhas desventuras com ponteiros inteligentes shared_ptr. Depois de implementar a geração do próximo nível em meu jogo Death-Mask, notei uma memória vazar . Cada novo nível proporcionou um aumento de + 1 megabyte na RAM consumida. É Obviamente que alguns objetos permaneceram na memória e não a liberaram. Para corrigir este facto, foi necessário implementar a correcta implementação de recursos quando o nível se encontra sobrecarregado, o que aparentemente não foi feito. Como usei ponteiros inteligentes, havia várias opções para resolver esse problema, a primeira envolvia a revisão manual do código (longa e enfadonha), enquanto a segunda envolvia pesquisar os recursos do depurador lldb e do código-fonte libstdc++ para a possibilidade de rastreamento automático contra alterações.

Na Internet, todos os conselhos se resumiam a revisar manualmente o código, corrigi-lo e bater-se com chicotes depois de encontrar a linha de código problemática. Também foi proposta a implementação de um sistema próprio para trabalhar com memória, como fazem todos os grandes projetos desenvolvidos desde as décadas de 90 e 2000, antes da chegada dos ponteiros inteligentes no padrão C++11. Tentei usar pontos de interrupção no construtor de uma cópia de todos os shared_ptrs, mas depois de vários dias nada de útil aconteceu. Houve uma ideia de adicionar log à biblioteca libstdc++, mas os custos de mão de obra acabaram sendo monstruosos.


Cowboy Bebop (1998)

A solução me ocorreu de repente na forma de rastrear alterações na variável privada shared_ptr – use_count. Isso pode ser feito usando watchpoints embutidos no lldb. Depois de criar um shared_ptr via make_shared, as alterações no contador no lldb podem ser rastreadas usando a linha:
.

assistir definir var camera._M_refcount._M_pi->_M_use_count

Onde a “câmera” este é um objeto shared_ptr cujo estado do contador precisa ser rastreado. Claro, os aspectos internos do shared_ptr irão variar dependendo da versão do libstdc++, mas o princípio geral pode ser entendido. Após instalar o watchpoint, iniciamos os aplicativos e lemos o stacktrace de cada alteração do contador, depois olhamos o código (sic!), encontramos o problema e corrigimos. No meu caso, os objetos não foram liberados das tabelas de cache e das tabelas lógicas do jogo. Espero que este método ajude você a lidar com vazamentos ao trabalhar com shared_ptr e ame ainda mais essa ferramenta de memória. Boa depuração.

Visão de Jogos #3

A terceira edição de uma coluna não permanente sobre jogos Games Vision.

Observer (PC e consoles, Bloober Team) – horror cyberpunk dos valentes poloneses. Um filme de terror curto e muito atmosférico estrelado por Rutger Hauer. Como fã de cyberpunk, gostei de absolutamente tudo no jogo. Enigmas não muito difíceis, falhas encantadoras do personagem principal, jogabilidade com momentos calmos misturados com ação, capacidade de literalmente mergulhar nas memórias dos mortos, um enredo no estilo Ghost in the Shell + muitas referências à cultura pop Sci-Fi. Dos pontos negativos – muitas falhas, às vezes parece que devido à sua abundância é impossível jogar, também alguns jogadores ficaram furiosos com elementos específicos de terror que eram tão assustadores que não conseguiam continuar jogando.
Avaliação: 8/10

Paradigma (Windows/OS X, Jacob Janerka) – uma busca que consegue parodiar e rir de tudo ao mesmo tempo. Há o ridículo da URSS, da América, do gênero quest, do glam rock, dos consoles antigos, das pessoas, dos monumentos, do pessoal de TI, dos cones, dos computadores, das mulheres, das crianças, dos pais, dos artistas, do amor, dos cientistas, da indústria de jogos, dos próprios jogadores e #8211; Em geral, é impossível listar tudo. Enredo absolutamente imprevisível, atmosfera e arte absurdas, enigmas não particularmente difíceis. O jogo possui bugs e travamentos raros, alguns momentos e piadas são um pouco previsíveis e nada originais.
Avaliação: 9/10

Late Shift (PC e consoles, CtrlMovie Ltd) – filme interativo. Lamento muito que uma ideia basicamente boa tenha sido implementada tão mal. Tudo está ruim – enredo, falta de atores estelares, atuação, congelamentos constantes na versão para PC, variabilidade quase zero (ilusória). É completamente incompreensível como foi possível lançar um jogo com tantos problemas na década de 2010, porque na verdade é um reprodutor de vídeo comum, o jogo inteiro poderia ter sido postado na Internet, por exemplo no YouTube, mas em vez disso eles usaram Unity e conseguiu quebrar um mecanismo de jogo tão poderoso. O fórum oficial do Steam é dedicado a correções, hotfixes, soluções alternativas, etc. Há um desastre técnico, falta de suporte ao usuário, todos os testes acontecem diretamente nos jogadores. Comprei ótimas críticas e depoimentos.
Avaliação: 3/10

Linguagem de programação ascendente

Apresento a vocês minha própria linguagem de programação chamada – Levante-se. Um transpilador de Rise para JavaScript está disponível no momento.

Você pode ver e usar no link abaixo – Rise em JavaScript (dialeto ECMAScript 5):
https://gitlab.com/demensdeum/Rise

Apresento também a sua atenção um aplicativo de demonstração inteiramente escrito em Rise:

Código-fonte do aplicativo de demonstração Rise:
https://gitlab.com/demensdeum/RiseDemoApplication

Você pode escrever para me se quiser tenho ideias, sugestões, comentários sobre o novo idioma.

Núcleo da corrupção

Era difícil respirar; o visor do capacete mostrava o suprimento de oxigênio por exatamente meia hora. Durante este tempo, Revil planejou chegar ao centro da cidade e obter a Máscara da Morte. Havia uma névoa verde acre ao redor, não havia ar aqui, pessoas meio mortas vagavam pelas ruas, criaturas capturadas pela influência da Máscara.
O som de passos se espalhava pelas salas vazias do prédio abandonado, Revil se movia com cautela, sem saber o que esperar no local mais perigoso do Technolab.

Não se mova!
por M-Delcambre

A cidade há muito foi capturada pela corrupção, mas não pela corrupção terrena, que escraviza as mentes dos políticos e dos sedentos de poder. A corrupção da Máscara da Morte toma conta da mente dos seres vivos, eles perdem o controle de si mesmos e passam a viver para realizar seus desejos. Todos aqueles que ficaram sob a influência começaram a acreditar que receberiam a vida eterna como resultado de seu serviço. Para manter o controle, a Máscara exige um fluxo constante de novos escravos e a captura de novos territórios com criaturas puras.

No noroeste, Revil viu o brilho azul sobre o qual Alice lhe contou; no centro dele está um enorme edifício criado pelos construtores do Technolab; Um estranho e grotesco acúmulo de estruturas salientes e peças mecânicas, como se tivessem sido criadas por um louco, tinha uma aparência assustadora.

Revil desceu da janela do prédio para a rua para continuar sua jornada, quando de repente ouviu o forte impacto de membros de metal no asfalto. Virando-se, ele viu o Demônio na sua frente – uma criatura biomecânica com três cabeças humanas, semelhante a uma aranha, movia-se lentamente em sua direção. Um círculo de uma estranha cor preta espelhada apareceu no céu, era difícil desviar os olhos. Houve um rugido ensurdecedor da sirene da cidade, chamando criaturas escravas para ajudar o Demônio. A situação estava muito ruim, mas Revil tinha uma surpresa preparada para este caso…

Sabre-Plus C++ IDE

Comecei a desenvolver meu próprio IDE para C++ – Sabre-Plus. As principais ideias do novo IDE – seja simples, rápido e *útil* no desenvolvimento. No momento, o código-fonte está disponível sob a licença MIT no GitHub. Qt é usado para trabalhar com a UI. No futuro pretendo transferir todo o desenvolvimento relacionado ao C++ para o Sabre-Plus – A Máscara da Morte definitivamente será migrada. Mais detalhes sobre os pontos:

  • Simples – está planejado não adicionar mais do que o necessário – por exemplo, não contêm clientes de controle de origem, terminais integrados e coisas semelhantes. A funcionalidade é focada apenas na edição de código e análise de erros. O código do editor deve ser dividido em classes simples que façam sua parte do trabalho corretamente (modo Unix)
  • Rápido – diz respeito tanto à base de código IDE quanto ao comportamento do próprio editor. Todas as ações no IDE devem ser o mais rápidas possível, mesmo aquelas muitas vezes longas e complexas como a criação/importação de projetos.
  • Ajudando – análise de erros típicos ao escrever e compilar código. Correção de erros e avisos mediante solicitação do usuário. O plano é adicionar uma análise do aplicativo construído em uma plataforma específica e exibir informações de ajuda sobre a instalação das bibliotecas e componentes necessários.

Para construir o editor para seu sistema operacional, você precisa instalar o Qt 5 SDK, baixar o código IDE do repositório, abrir o arquivo Saber-Plus.pro no Qt Creator e executar a compilação:

https://github.com/demensdeum/saberplus