Biblioteca para manejar señales con C++

Aquí los desarrolladores anuncian las mejoras de pilas, nuevas versiones, tutoriales o eventos.

Biblioteca para manejar señales con C++

Notapor hugoruscitti » Lun Ago 23, 2010 11:10 pm

Saludos, quería comentarles que investigando algunas cosillas
con C++ he visto que hay una biblioteca para manejar señales. Y
por lo poquito que ví es muy parecida a la que estoy usando
en pilas (el dispatcher de django).

La blblioteca en cuestión es libsigc:

http://libsigc.sourceforge.net/

tiene un buen tutorial:

http://library.gnome.org/devel/libsigc+ ... al/stable/

e incluso la sintaxis se asemeja mucho a lo que
estoy implementando en pilas:

Código: Seleccionar todo
// declaracion
sigc::signal<void> senal_o_evento;

// conectar
senal_o_evento.connect( sigc::ptr_fun(funcion_a_ejecutar));

// emitir
senal_o_evento.emit();


Espero que les resulte útil, saludos a todos.
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina

Re: Biblioteca para manejar señales con C++

Notapor Juanxo » Lun Ago 23, 2010 11:55 pm

gran aportación hugo. Tendremos que echarle un vistazo
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Re: Biblioteca para manejar señales con C++

Notapor carlostex » Mar Ago 24, 2010 3:01 am

Exelente es facil de usar, nos servirá mucho, gracias
El conocimiento de unos es conocimiento de todos.
Avatar de Usuario
carlostex
 
Mensajes: 249
Registrado: Mar Jul 14, 2009 4:13 am
Ubicación: mexico

Re: Biblioteca para manejar señales con C++

Notapor Geo » Vie Ago 27, 2010 6:04 am

Empecé a hacer pruebas con esta biblioteca, me parece bastante útil, aunque es la primera vez que uso algo como esto (lo único que había usado eran callbacks en C para una biblioteca GUI con SDL), aunque tengo un problema, agregué esto al código de prueba.cpp:
Código: Seleccionar todo
      else if ( evento.Type == sf::Event::MouseButtonPressed )
      {
        cout << "Clic de ratón en: " << evento.MouseMove.X << ", " << evento.MouseMove.Y << endl;
      }

Esto es lo que obtuve en la última ejecución:
./prueba
Clic de ratón en: 0, 495
Clic de ratón en: 0, 617
Clic de ratón en: 0, 148
Clic de ratón en: 0, 111
Clic de ratón en: 0, 302
Clic de ratón en: 0, 442
Clic de ratón en: 0, 648
Clic de ratón en: 0, 586
AL lib: ALc.c:1879: exit(): closing 1 Device
AL lib: ALc.c:1808: alcCloseDevice(): destroying 1 Context(s)
AL lib: ALc.c:1420: alcDestroyContext(): deleting 2 Source(s)
Inconsistency detected by ld.so: dl-close.c: 731: _dl_close: Assertion `map->l_init_called' failed!

Como ven, la posición X del ratón siempre queda en 0, no se a qué se deba, aunque no me agrada el último mensaje de la inconsistencia (no estoy enlazando con la biblioteca, sino con los módulos objeto individuales).
---------------------------
Edición:
Probado en Ubuntu 10.04 32 bits, g++ 4.4.3, SFML 1.5
Compilación:

g++ -o prueba prueba.o actores.o sonido.o texto.o -lsfml-audio -lsfml-window -lsfml-graphics -lsfml-system -Wall

Si, no estoy usando libPilas.so
Última edición por Geo el Vie Ago 27, 2010 6:20 am, editado 1 vez en total
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Re: Biblioteca para manejar señales con C++

Notapor Juanxo » Vie Ago 27, 2010 6:10 am

una cosa que tenemos que empezar a acostumbrarnos es dar un detalle de la prueba: que sistema hemos usado? xD

voy a ver si le hecho un vistazo
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Re: Biblioteca para manejar señales con C++

Notapor Geo » Vie Ago 27, 2010 6:40 am

Ya encontré el problema, no debía usar MouseMove sino MouseButton :p.

Código: Seleccionar todo
      else if ( evento.Type == sf::Event::MouseButtonPressed )
      {
        cout << "Clic de ratón en: " << evento.MouseButton.X << ", " << evento.MouseButton.Y << endl;
      }
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Re: Biblioteca para manejar señales con C++

Notapor carlostex » Sab Ago 28, 2010 12:33 am

pon el codigo completo
El conocimiento de unos es conocimiento de todos.
Avatar de Usuario
carlostex
 
Mensajes: 249
Registrado: Mar Jul 14, 2009 4:13 am
Ubicación: mexico

Re: Biblioteca para manejar señales con C++

Notapor Geo » Sab Ago 28, 2010 5:33 am

El código al que hacía referencia es el de pruebas.cpp, en la parte donde se evalúa el tipo de evento agregué el código que mostré para procesar los clics del ratón, por eso no puse todo:
Código: Seleccionar todo
/* Pilas engine - Un motor de videojuegos
*
* Copyright 2010 - Hugo Ruscitti
* Licencia: LGPLv3 (vea http://www.gnu.org/licenses/lgpl.html)

* Website - http://www.pilas-engine.com.ar
*
* El motor original está creado en Python,
* esta es la implementación en C++
* Lea el archivo AUTORES para saber quiénes la realizan.
*/

#include "actores.h"
#include "texto.h"
#include "sonido.h"
#include <vector>
using std::vector;
#include <iostream>
using std::cout;
using std::endl;

int main( int argc, char* argv[] )
{
  // Crea la ventana principal
  sf::RenderWindow ventana( sf::VideoMode( 800, 600 ), "PilasC++" );
 
  // Crea un nuevo actor de ejemplo
  Pilas::Mono mono;
 
  // Lo coloca al centro de la pantalla
  mono.establecer_x( 400 );
  mono.establecer_y( 300 );
 
  // Agranda 300% la imagen del mono
  mono.establecer_escala( 3 );
 
  // Actores en pantalla
  vector< Pilas::Actor* >actores;
  // Agrega actores al vector
  actores.push_back( &mono );

  // Texto en pantalla
  sf::Font fuente;
  fuente.LoadFromFile( "data/FreeMono.ttf" );
  Pilas::Texto mensaje( "Hola PilasC++\nPulsa [A] [B] o [C]", fuente, 20 );
  mensaje.establecer_color( sf::Color( 255, 255, 255 ) );

  //Creamos el evento solo una vez mejor
  // Procesa eventos.
  sf::Event evento;

  // Ciclo principal
  while( ventana.IsOpened() ) {
   
   
    while( ventana.GetEvent( evento ) ) {
      // Cierre de ventana
      if ( evento.Type == sf::Event::Closed )
        ventana.Close();

      // Presión de teclas. Mejor un switch, ya que nos evitamos tener que
      //ejecutar todos los condiciones en caso de que se de un evento
      else if ( evento.Type == sf::Event::KeyPressed ) {
        switch (evento.Key.Code)
        {
          case sf::Key::Escape:
            ventana.Close();
            break;
          case sf::Key::A:
            mono.establecer_rotacion( 0 );
            mono.normal();
            break;
          case sf::Key::B:
            // Gira imagen 45° en sentido horario
            mono.establecer_rotacion( 45 );
            mono.gritar();
            break;
          case sf::Key::C:
            // Gira imagen 45° en sentido antihorario
            mono.establecer_rotacion( -45 );
            mono.sonreir();
            break;
          default:
            break;
        }
      }
      else if ( evento.Type == sf::Event::MouseButtonPressed )
      {
        int* ptr = &evento.MouseMove.Y;
        cout << "Clic de ratón en: " << evento.MouseButton.X << ", " << evento.MouseButton.Y << endl;
        cout << "Clic de ratón en: " << evento.MouseMove.Y << ", " << *( ptr + 1 ) << endl;
        cout << "Ratón en: " << ventana.GetInput().GetMouseX() << ", " << ventana.GetInput().GetMouseY() << endl;
      }
    }
   
    // Limpia la pantalla
    ventana.Clear();

    // Dibuja los actores
    for ( unsigned i = 0; i < actores.size(); i++ )
    {
      ventana.Draw( *actores[ i ] );
    }

    // Mensajes de texto
    ventana.Draw( mensaje );
    // Actualiza pantalla
    ventana.Display();
   
    sf::Sleep( 0.1 );
  }

  return EXIT_SUCCESS;
}


Ahora, sobre las señales, tengo nuevamente dudas al comparar con la versión Python, en la que se definen clases para cada "comportamiento" pero, tal como con BaseActor, estas clases hacen uso de variables que no se heredan ni están declaradas, así se puede definir la clase SeguirAlMouse:
Código: Seleccionar todo
class SeguirAlMouse:
    "Hace que un actor siga la posición del mouse en todo momento."

    def __init__(self):
        pilas.eventos.mueve_mouse.connect(self.move)

    def move(self, sender, x, y, signal):
        self.x = x
        self.y = y

¿Cómo replicaríamos eso en C++? Había pensado en que, si se pudiera hacer una clase similar, después se crearía una nueva clase heredando de esta y del actor o elemento deseado:
Código: Seleccionar todo
class MonoSigueClics : public Pilas::Mono, public Pilas::SeguirAlMouse
...

El detalle, ¿de dónde debería heredar SeguirAlMouse para poder tener los atributos que la versión Python y que no haya que reescribir lo que se desea hacer en la función?
No se puede heredar de sf::Drawable, es abstracta, de sf::Sprite tampoco porque luego faltaría especificar si estamos modificando los atributos de Mono o de Sprite.

Entonces, lo que pensaba era que se deberían tener funciones virtuales para los eventos, y podrían estar dentro de una clase donde solo se tengan funciones virtuales, después crear una nueva clase mezclando esta clase abstracta y la de interés:
Código: Seleccionar todo
class EventosRaton
{
  virtual void al_hacer_clic( boton, x, y );
  virtual void al_soltar_boton( boton, x, y );
  virtual void al _mover_raton( x, y );
};

class MonoSigueClics : public Mono, public EventosRaton
{
  void al_hacer_clic( boton, x, y )
  {
    if ( boton == izquierdo )
    {
      establecer_x( x );
      establecer_y( y );
    }
  }
}

El detalle aquí es que no sería "combinar" con una clase que "sigue clics", sino de una que puede recibir valores relacionados con el evento del ratón y entonces escribir en su redefinición el código para mover el actor a la posición que se quiere.
¿Qué opinan?
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Re: Biblioteca para manejar señales con C++

Notapor Juanxo » Sab Ago 28, 2010 5:47 am

un solo apunte que te vendrá bien en tu iniciacion en C++:

es_un vs tiene_un:

una clase hereda de otra si la relacion es del tipo es_un: Un PERRO es un Animal.

una clase tiene un atributo de otra si la relación es del tipo tiene_un: Un SOLDADO tiene una ESPADA, pero no es una espada.

Por eso quizás podríamos tener una lista de componentes (o habilidades en cada Actor) y actualizarlas en el update o algo de este estilo
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Re: Biblioteca para manejar señales con C++

Notapor carlostex » Sab Ago 28, 2010 6:30 am

Que tal? pues platicando con juan nos pareció bien la siguiente idea:

Crear un observador; es una clase que contiene las funciones como: seguir_raton, arrastrar, etc.
y un vector de apuntadores a base_entidad (pensamos en poner una clase base)

entonces para poner un comportamiento seria:
comportamientos.seguir_mouse(&mono);
comportamientos.seguir_mouse(&texto);
esta clase se actualizaria cada que se detecte un evento:
Código: Seleccionar todo
    while( ventana.IsOpened() ) {
   
    while( ventana.GetEvent( evento ) ) {
      // Cierre de ventana
      if ( evento.Type == sf::Event::Closed )
        ventana.Close();

     
      else if ( evento.Type == sf::Event::MouseButtonPressed )
      {
        comportamientos.actualizar_evento("Button Pressed");//actualiza a todas las entidades asociadas a ese evento
        // o button_pressed() directamente
      }
    }


Me gusta mas usar actializar_evento y con una constante decir que tipo es, ademas se requeriria mas memoria para cada función por tipo de evento

la clase comportamientos la pondria como singleton , pues no debe haber mas de un controlador.
El conocimiento de unos es conocimiento de todos.
Avatar de Usuario
carlostex
 
Mensajes: 249
Registrado: Mar Jul 14, 2009 4:13 am
Ubicación: mexico

Re: Biblioteca para manejar señales con C++

Notapor Juanxo » Sab Ago 28, 2010 6:49 am

nunca, nunca, casi nunca, utilices un singleton xD. Es tontería. Si solo quieres un objeto, no crees más xD
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Re: Biblioteca para manejar señales con C++

Notapor carlostex » Sab Ago 28, 2010 7:12 am

ok, ok, ok jaja, nunca las he usado, y si he leido que se pueden solucionar de otra forma mas sencilla, pues dejemos que experimenten usando mas controladores
aver que se les ocurre(a los usuarios).
El conocimiento de unos es conocimiento de todos.
Avatar de Usuario
carlostex
 
Mensajes: 249
Registrado: Mar Jul 14, 2009 4:13 am
Ubicación: mexico


Volver a Anuncios de los desarrolladores

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados

cron