aboutsummaryrefslogtreecommitdiff
path: root/src/MTools/MObjet.pm
blob: ab015d5a219b8bb44b596c288cd523cf2e0b1190 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package MTools::MObjet;
#	This program is free software; you can redistribute it and/or
#	modify it under the terms of the GNU LGPL Libray General Public License
#	as published by the Free Software Foundation; either version 2
#	of the License, or (at your option) any later version.
#
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU Library General Public License for more details.
#
#	You should have received a copy of the GNU Library General Public License
#	along with this program; if not, write to the Free Software
#	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA,
#	or refer to http://www.gnu.org/copyleft/lgpl.html
#
##################################################################

# Le composant MObjet est l'objet racine des composants MTools. 
# Il definit les fonctions applicables uniquement aux objets MTools. 
#
# IMPORTANT : Une autre partie des fonctions applicables aux objets MTools est definie dans la classe MTools. 
# La difference entre ces deux classes de fonctions est que les fonctions definies dans MTools sont egalement
# applicables ? des objets zinc tandis que les fonctions definies ici ne peuvent etre appliquees que a des objets heritant de MTools::MObjet.
#
# Concepts :
#	* Objet MTools : objet heritant de MObjet
#	* Les PROPERTY :  Les proprietes sont des attributs particuliers et modifiables
#	par un appel a "mconfigure". Elles peuvent etre ecoutees et synchronisees avec d'autres proprietes 
#	MTools ou meme zinc ! (cf MTools::plink et MTools::plisten). En consequence elles sont la pour engendrer un comportement 
#	consecutif ? leur modification et doivent etre distinguees des attibuts qui peuvent se contenter d'etre ds clef de hash de l'objet.
#	* Les EVENT : les evenements peuvent etre emis par n'importe quel objet MTools et capter par un binding.
#
# Les fonctions public :
# 	* recordEvent : permet de permettre a un objet MObjet d'emettre un evenement.
# 	* recordProperty : permet de declarer et initialiser une propriete.
# 	NOTA : Il pourrait manquer une declaration collective des proprietes. Initialement, 
#	celle-ci n'a pas ete effectuee pour essayer de limiter l'usage des proprietes 
#	et ne pas les utiliser comme des attributs. 
#	* notify : permet a un objet MTools de notifier un evenement prealablement enregistre par recordEvent
#	* propagate : permet a un objet de propager un evenement emis par un autre objet 
#	(correspond a un recordEvent puis un binding sur un evenement d'un objet effectuant le notify du meme evt 
#	depuis l'objet declarant la propagation)

use strict;
use MTools;
use vars qw /@ISA @EXPORT @EXPORT_OK/;

BEGIN 
{
	@ISA = qw //;
}

sub new {
	my ($class) = @_;
	my $self = {};
	$self -> {instance} = -1;
	bless $self, $class;
	return $self;
}

sub recordEvent {
	my ($self, $event) = @_;
	if (!(defined $self -> {__events} -> {$event}))
	{
		$self -> {__events} -> {$event} = [];
	}
}

sub recordProperty {
	my ($self, $prop, $val) = @_;
	$self -> {__properties} -> {$prop} -> {val} = $val;
}

sub notify {
	my ($self, $event, @params) = @_;
	if (!defined $self -> {__events} -> {$event})
	{
		print "ERREUR $self : Vous essayer de notifier l'evenement $event qui n'est pas declare\n";
		return;
	}
	my @tb = @{$self -> {__events} -> {$event}};
	for (my $i = 0; $i < @tb; $i++)
	{
		executer ($tb[$i], @params);
	}
}

sub propagate {
	my ($self, $from, $event, @nargs) = @_;
	$self -> recordEvent ($event);
	$from -> __addListener ($event, 
		sub { 
			my (@args) = @_; 
			$self -> notify  ($event, @args, @nargs);
		}
	);
}

sub __addListener {
	my ($self, $event, $methode) = @_;
	if (defined $self -> {__events} -> {$event})
	{
		push (@{$self -> {__events} -> {$event}}, $methode);
		return $methode;
	}
	else
	{
		print "ERREUR : l'objet $self n'?met jamais l'evt $event... L'abonnement est donc inutile\n";
	}
}

sub __removeListener {
	my ($self, $event, $methode) = @_;
	if (defined $self -> {__events} -> {$event})
	{
		my @events = @{$self -> {__events} -> {$event}};
		for (my $i = @events - 1; $i >= 0; $i--) 
		{
			if ($events [$i] == $methode) 
			{
				splice (@{$self -> {__events} -> {$event}}, $i, 1);
			}
		}
	}
}

1;