1. Introdução

O que é um componente?

Componentes Gambas são bibliotecas compartilhadas escritas em C ou C++ que adicionam novas funções ao interpretador Gambas.

Eles agem como drivers Linux através do kernel Linux:

  • Os componentes e o interpretador comunicam através da Interface de Programação Gambas.

  • Eles devem ser compilados dentro do pacote de fontes Gambas.

  • Eles são executados dentro do ambiente do interpretador, e então não podem fazer qualquer coisa que quiserem.

Um componente pode conter:

  • Novas classes que são adicionadas a outras classes Gambas. Essas classes são declarada para um interpretador usando uma estrutura C que contém a descrição de cada símbolo, método, constante e evento.

  • Hooks do Interpretador: funções que implementam operações importantes do interpretador, como gerenciar o loop de eventos, ler os parâmetros do programa...

  • Uma interface de programação que melhora a Interface de programação Gambas, e que outros componentes podem usar.

Um componente deve ter um nome. Este nome é a palavra gb seguida de uma lista de palavras separadas por pontos descrevendo o papel do componente e outro componente que ele depende, se existir.

Por exemplo, gb.qt.kde é um componente que transforma aplicações Gambas em uma aplicação KDE. Este componente depende do componente gb.qt4, i.e. carregando o primeiro implica o garregamento do segundo.

A Interface de Programação Gambas

A Interface de Programação Gambas é um conjunto de utilitários, funções e macros que permitem que você:
  • Descreva o componente.

  • Defina hooks do interpretador.

  • Manipule arrays, tabelas hash...

  • Manipule tipos de dados nativos do Gambas.

  • Grie arrays e coleções Gambas.

  • Cause eventos.

  • Manipule objetos Gambas.

  • Carregue um arquivo do grupo de arquivos do projeto.

  • Carregue outros componentes.

  • ...

O uso desta interface de programação é altamente recomendado, já que isso previne que um componente faça coisas estranhas.

A Interface de Programação Gambas é uma estrutura C que contém um ponteiro de função para cada função da interface.

Esta estrutura é declarada no arquivo principal do seu componente e é automaticamente inicializado pelo interpretador no carregamento de componentes.

Escrevendo Bons Componentes

Escrever bons componentes é a parte difícil! Vamos supor que você queira escrever um componente SDL, i.e. um componente que permite que os projetos Gambas usem todo o poder da biblioteca SDL: gráficos, som, CD-ROM...

Você pode se contentar com apenas empacontar as funções, estruturas e constantes da biblioteca. Esse é o jeito fácil, mesmo que empacotar estruturas C e funções não possa ser possível em cada caso com o Gambas.

Seu componente será útil, mas não muito interessante para o programador Gambas, porque ele será obrigado a programar no estilo C ou C++.

Ao invés disso, você deve quebrar a cabeça para criar uma interface diferente entre o Gambas e a biblioteca, tentando generalizar e simplificar a interface original da biblioteca.

O que eu fiz com o QT: é mais fácil usar o componente QT do que programar a biblioteca QT diretamente. E se algum dia alguem escrever um componente GTK+, ele conseguirá usar a mesma interface porque eu tentei generalizar a interface QT evitando todas as coisas específicas do QT... Bem, pra ser honesto, eu coloquei todas as coisas específicas e úteis do QT dentro de um componente estendido dedicado, gb.qt.ext

Organização dos Fontes dos Componentes

Os arquivos fontes de um componente são armazenados em um sub-diretório do diretório lib do pacote de fontes. O caminho deste diretório reflete o nome do componente.

Por exemplo, o fontes do componente gb.qt.kde estão armazenados no diretório .src/lib/qt/kde.

Um diretório de componentes típico contem:
  • Os objetos autoconf/automake, i.e. um arquivo Makefile.am que descreve como compilar o componente. (novo tópico)

  • Um arquivo fonte e um arquivo header para cada classe principal implementada no componente.

  • Um arquivo principal que implementa os pontos de entrada do componente.

  • Um arquivo de descrição do componente.

Por exemplo, aqui está o resultado de ls ./src/lib/qt/kde pouco antes da compilação:

CApplication.cpp  CDatePicker.cpp  CDialog.cpp  lib.gb.qt.kde.component  main.h    Makefile.am
CApplication.h    CDatePicker.h    CDialog.h    main.cpp                 Makefile  Makefile.in

A estrutura de diretórios do fonte do componente parece com algo deste tipo:

-+- lib
 |
 +---+- db
 |   |
 |   +----- mysql
 |   |
 |   +----- postgresql
 |
 +----- eval
 |
 +----- example
 |
 +----- net
 |
 +---+- qt
 |   |
 |   +----- editor
 |   |
 |   +----- ext
 |   |
 |   +----- kde
 |
 +----- sdl