1/*
2 * Copyright 2007-2014 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Niels Sascha Reedijk, niels.reedijk@gmail.com
7 *		John Scipione, jscipione@gmail.com
8 *
9 * Corresponds to:
10 *		headers/os/app/Handler.h	hrev47355
11 *		src/kits/app/Handler.cpp	hrev47355
12 */
13
14/*!
15	\file Handler.h
16	\ingroup app
17	\ingroup libbe
18	\brief Provides the BHandler class.
19*/
20
21
22///// Globals /////
23
24
25/*!
26	\def B_OBSERVE_WHAT_CHANGE
27	\brief Internal.
28
29	\since BeOS R5
30*/
31
32
33/*!
34	\def B_OBSERVE_ORIGINAL_WHAT
35	\brief Constant for a message data field in observer messages.
36
37	If you have called one of the flavors of BHandler::StartWachting(), and
38	you receive a notification, sometimes there can be send a BMessage to go
39	with that notification. The message you receive is a copy of that message,
40	but with the what constant set to \c B_OBSERVER_NOTICE_CHANGE. The original
41	\c what constant of the transmitted data message is stored behind the
42	label defined by this constant.
43
44	\since BeOS R5
45*/
46
47
48/*!
49	\var B_OBSERVER_OBSERVE_ALL
50	\brief Parameter to BHandler::StartWatching().
51	
52	\note Specifying this parameter as the \a what value, leads to the same
53		results as calling BHandler::StartWatchingAll().
54
55	\since BeOS R5
56*/
57
58
59///// BHandler /////
60
61
62/*!
63	\class BHandler
64	\ingroup app
65	\ingroup libbe
66	\brief Handles messages that are passed on by a BLooper.
67
68	The BHandler class implements two important pieces of functionality. It
69	provides the foundations for <b>handling messages</b>, and it serves as a
70	<b>state machine</b> that sends out notifications of the state changes.
71
72	The most common use of this class is to <b>handle messages</b>. Handlers
73	can be tied to loopers, which are the objects that send and receive
74	messages. As soon as a message is received, the looper passes through its
75	list of associated handlers and tries them in a certain order until the
76	message is handled, or the options are exhausted.
77
78	You should know that a looper is a subclass of a handler, and as such,
79	loopers can be self-contained and do not need additional handlers. In many
80	cases, this construction will suffice. You will simply subclass the looper,
81	override its MessageReceived() hook and handle the messages you receive. In
82	some cases, you might opt in for a more ingenious construction. A
83	real-world example is the interface kit. Within that kit, the windows are
84	represented by a BLooper, and all the views and controls in that kit are
85	derived from BHandler. If you put a control in a window, then whenever
86	messages such as clicks are received, the window loops the handlers until
87	there is a handler that is at the screen position the click was in. It is
88	not unlikely that you will some day want to use this functionality of the
89	API.
90
91	If your handler is limited to a certain type of messages, you can set a
92	filter that the looper will apply to your message before passing it on to
93	your overridden MessageReceived() method. The BMessageFilter class provides
94	the framework for the flexible filtering options, and using AddFilter() you
95	can apply filters to this handler. Note that a filter object should only be
96	applied to one handler. They cannot be shared.
97
98	For more information on the handling chain, have a look at the
99	documentation of the BLooper class.
100
101	Using BHandler as a <b>state machine</b> is a second area of functionality.
102	Since handlers process messages, and perform actions associated with those,
103	they are the center of keeping track on the current state of things within
104	an application. If you want to synchronize these states between different
105	parts of your application, you could perform this manually by sending
106	messages to the interested components, or you can use the more flexible
107	approach with observers.
108
109	Observers watch a certain state. A handler can track one or more different
110	states. Each state is represented by a four byte constant - just like the
111	\c what property of a message. Using the StartWatching() methods, you can
112	register observers both within your team, and in other applications. As an
113	argument of that method, you can supply the state you want to watch, or you
114	can register an observer using StartWatchingAll() to watch all the states
115	the handler tracks. When the handler needs to emit a state change, you can
116	use SendNotices(). You can specify the exact state change, and some data
117	that you want to be send to the observers. This data is in the form of the
118	very flexible BMessage, as such you are almost free to pass anything you
119	want.
120
121	Whenever SendNotices() is called, all interested observers will receive a
122	message of the \a B_OBSERVER_NOTICE_CHANGE type. Please note that the
123	constant that is associated with the state itself is not transmitted. If
124	you require this information, consider using the message that is passed
125	on to describe the state change.
126
127	BHandler is a part of the chain in the eloquent messaging structure. For a
128	proper understanding of all its facets, have a look at the \ref app_messaging
129	"messaging overview".
130
131	\since BeOS R3
132*/
133
134
135/*!
136	\fn BHandler::BHandler(const char* name)
137	\brief Construct a new handler with a \a name.
138
139	The newly constructed handler is not associated with a looper until you
140	explicitly request this to happen. To associate this handler with a looper,
141	use BLooper::AddHandler().
142
143	\since BeOS R3
144*/
145
146
147/*!
148	\fn BHandler::~BHandler()
149	\brief Free the filters of this handler, as well as the list of observers.
150
151	This method does not remove the handler from the looper to which this
152	handler is associated. You should do this yourself, using
153	BLooper::RemoveHandler().
154
155	\warning This constructor does no type check whatsoever. Since you can pass
156		any BMessage, you should - if you are not sure about the exact type -
157		use the Instantiate() method, which does check the type.
158
159	\since BeOS R3
160*/
161
162
163/*!
164	\fn BArchivable* BHandler::Instantiate(BMessage* data)
165	\brief Static method to instantiate a handler from an archived message.
166
167	\return A pointer to the instantiated handler, or \c NULL if the \a data
168		is not a valid archived BHandler object.
169
170	\see BHandler(BMessage* data)
171
172	\since BeOS R3
173*/
174
175
176///// Archiving /////
177
178/*!
179	\name Archiving
180
181	BHandler inherits the BArchivable class, and as such implements support for
182	archiving and unarchiving handlers.
183*/
184
185
186//! @{
187
188
189/*!
190	\fn BHandler::BHandler(BMessage* data)
191	\brief Construct a handler from an archived message.
192
193	This \a data has to be created using the BHandler::Archive() method.
194	Note that only the name is stored. The filters, the associated looper and
195	the observers are not stored, and should be manually added when you are
196	using this object.
197
198	\since BeOS R3
199*/
200
201
202/*!
203	\fn status_t BHandler::Archive(BMessage* data, bool deep) const
204	\brief Archive a handler to a message
205
206	Currently, only the name is archived. The filters, the associated looper
207	and the observers are not stored. 
208
209	\param data The message to archive the object in.
210	\param deep This parameter is ignored, as BHandler does not have children.
211
212	\return A status code.
213	\retval B_OK Archiving succeeded.
214	\retval B_BAD_VALUE The \a data parameter is not a valid message.
215
216	\see BHandler::Instantiate(BMessage* data)
217
218	\since BeOS R3
219*/
220
221
222//! @}
223
224
225///// The guts of BHandler /////
226
227
228/*!
229	\name Core Handler Functionality
230*/
231
232
233//! @{
234
235
236/*!
237	\fn void BHandler::MessageReceived(BMessage* message)
238	\brief Handle \a message that has been received by the associated looper.
239
240	This method is reimplemented by subclasses. If the messages that have
241	been received by a looper pass through the filters, then they end up in
242	the MessageReceived() methods.
243
244	The example below shows a very common way to handle \a message. Usually,
245	this involves parsing the BMessage::what constant and then perform an
246	action based on that. 
247
248\code
249void
250ShowImageApp::MessageReceived(BMessage *message)
251{
252	switch (message->what) {
253		case MSG_FILE_OPEN:
254			fOpenPanel->Show();
255			break;
256
257		case B_CANCEL:
258			// File open panel was closed,
259			// start checking count of open windows.
260			StartPulse();
261			break;
262		
263		default:
264			// We do not handle this message, pass it on to the base class.
265			BApplication::MessageReceived(message); 
266			break;
267	}
268}
269\endcode
270
271	If your handler cannot process this \a message, you should pass it on
272	to the base class. Eventually, it will reach the base implementation,
273	which will reply with \c B_MESSAGE_NOT_UNDERSTOOD.
274
275	\attention If you want to keep or manipulate the \a message, have a
276	           look at BLooper::DetachCurrentMessage() to receive ownership
277	           of the \a message.
278
279	\param message The message that needs to be handled.
280
281	\since BeOS R3
282*/
283
284
285/*!
286	\fn BLooper* BHandler::Looper() const
287	\brief Return a pointer to the looper that this handler is associated with.
288
289	\return If the handler is not yet associated with a looper, it will return
290	        \c NULL.
291
292	\see BLooper::AddHandler()
293	\see LockLooper()
294
295	\since BeOS R3
296*/
297
298
299/*!
300	\fn void BHandler::SetName(const char *name)
301	\brief Set or change the name of this handler.
302
303	\see Name()
304
305	\since BeOS R3
306*/
307
308
309/*!
310	\fn const char* BHandler::Name() const
311	\brief Return the name of this handler.
312
313	\see SetName()
314
315	\since BeOS R3
316*/
317
318
319/*!
320	\fn void BHandler::SetNextHandler(BHandler* handler)
321	\brief Set the next handler in the chain that the message is passed on to
322	       if this \a handler cannot process it.
323
324	This method has three requirements:
325	-# This \a handler should belong to a looper.
326	-# The looper needs to be locked. See LockLooper().
327	-# The \a handler that you pass must be associated with the same looper.
328
329	Failure to meet any of these requirements will result in your application
330	crashing.
331
332	By default, the handlers are chained in order that they were associated to
333	a looper with BLooper::AddHander().
334
335	\see NextHandler()
336
337	\since BeOS R3
338*/
339
340
341/*!
342	\fn BHandler* BHandler::NextHandler() const
343	\brief Return the next hander in the chain to which the message is passed
344	       on.
345
346	\see SetNextHandler()
347
348	\since BeOS R3
349*/
350
351
352//! @}
353
354
355///// Message Filtering /////
356
357
358/*!
359	\name Message Filtering
360*/
361
362
363//! @{
364
365
366/*!
367	\fn void BHandler::AddFilter(BMessageFilter *filter)
368	\brief Add \a filter as a prerequisite to this handler.
369
370	If the handler is associated with a looper, this looper needs to be locked
371	in order for this operation to succeed.
372
373	Note that the filter is not copied, rather a pointer to the \a filter is
374	stored. As such, you need to make sure that the \a filter object exists as
375	long as it is added to this handler.
376
377	\see RemoveFilter()
378	\see SetFilterList()
379
380	\since BeOS R3
381*/
382
383
384/*!
385	\fn bool BHandler::RemoveFilter(BMessageFilter* filter)
386	\brief Remove \a filter from the filter list.
387
388	If the handler is associated with a looper, this looper needs to be locked
389	in order for this operation to succeed.
390
391	Note that the \a filter is not deleted, merely removed from the list. You
392	need to take care of the memory yourself.
393
394	\return \c true if the \a filter was in the filter list and is removed,
395	        \c false if the \a filter was not found in the filter list.
396
397	\see AddFilter()
398	\see FilterList()
399
400	\since BeOS R3
401*/
402
403
404/*!
405	\fn void BHandler::SetFilterList(BList* filters)
406	\brief Set the internal list of filters to \a filters.
407
408	If the handler is associated with a looper, this looper needs to be locked
409	in order for this operation to succeed.
410
411	The internal list will be replaced with the new list of \a filters. All the
412	existing filters will be \b deleted.
413
414	\see AddFilter(), FilterList()
415
416	\since BeOS R3
417*/
418
419
420/*!
421	\fn BList* BHandler::FilterList()
422	\brief Return a pointer to the list of filters.
423
424	\return A pointer to the list of filters. Do not manipulate the list of
425	        filters directly, but use the methods provided by this class, in
426	        order to maintain internal consistency.
427
428	\see AddFilter()
429	\see RemoveFilter()
430	\see SetFilterList().
431
432	\since BeOS R3
433*/
434
435
436//! @}
437
438
439///// Locking /////
440
441
442/*!
443	\name Locking
444
445	This class provides some utility functions to lock the looper associated
446	with this handler.
447*/
448
449
450//! @{
451
452
453/*!
454	\fn bool BHandler::LockLooper()
455	\brief Lock the looper associated with this handler.
456
457	\return \c true if the looper is locked, \c false if there was an error
458	        acquiring the lock.
459
460	\see LockLooperWithTimeout()
461	\see UnlockLooper()
462
463	\since BeOS R4
464*/
465
466
467/*!
468	\fn status_t BHandler::LockLooperWithTimeout(bigtime_t timeout)
469	\brief Lock the looper associated with this handler, with a time out value.
470
471	\param timeout The time to wait for acquiring the lock in microseconds. You
472	       may also use \c B_INFINITE_TIMEOUT, in which this method will wait
473	       as long as it takes to acquire the lock.
474
475	\return A status code.
476	\retval B_OK Locking succeeded.
477	\retval B_BAD_VALUE This handler is not associated with a looper (anymore).
478	\retval B_TIMED_OUT The time specified in \a timeout has passed without
479		locking the looper.
480
481	\see LockLooper()
482	\see UnlockLooper()
483
484	\since BeOS R4
485*/
486
487
488/*!
489	\fn void BHandler::UnlockLooper()
490	\brief Unlock the looper.
491
492	\since BeOS R4
493*/
494
495
496//! @}
497
498
499///// Scripting //////
500
501
502/*!
503	\name Scripting
504*/
505
506
507//! @{
508
509
510/*!
511	\fn BHandler* BHandler::ResolveSpecifier(BMessage* message, int32 index,
512		BMessage* specifier, int32 what, const char* property)
513	\brief Determine the proper handler for a scripting message.
514
515	\param message The scripting message to determine the handler.
516	\param index The index of the specifier.
517	\param specifier The message which contains the specifier.
518	\param what The 'what' field of the specifier message.
519	\param property The name of the target property.
520
521	\return A pointer to the proper BHandler for the given scripting
522	        message.
523
524	\since BeOS R3
525*/
526
527
528/*!
529	\fn status_t BHandler::GetSupportedSuites(BMessage* data)
530	\brief Reports the suites of messages and specifiers that derived classes
531	       understand.
532
533	\since BeOS R3
534*/
535
536
537//! @}
538
539
540///// Observing /////
541
542
543/*!
544	\name Observing
545
546	Handlers can function as state machines, which emit messages to observers
547	when the state changes. Use the following methods to subscribe to these
548	notifications.
549
550	Note that there is a semantic difference between the two StartWatching()
551	methods. The overloaded method that accepts a BHandler, expects as
552	argument an \a observer that watches this handler. The method that
553	accepts a BMessenger, expects a \a target that emits the state changes
554	to this handler.
555*/
556
557
558//! @{
559
560
561/*!
562	\fn status_t BHandler::StartWatching(BMessenger target, uint32 what)
563	\brief Subscribe this handler to watch a specific state change of a
564	       \a target.
565
566	Use this method to subscribe messengers to watch state changes in this
567	handler, this also means that observers from other teams can be
568	subscribed.
569
570\code
571// Handler B watches Handler A
572BHandler A, B;
573BMessenger messengerA(&A)
574
575B.StartWatching(messengerA, kNetworkConnection);
576\endcode
577
578	\param target The messenger from which the notifications would be received.
579	\param what The state that needs to be watched.
580
581	\return During the call of this method, a notification will be transmitted
582	        using the \a target. If this works, then this method will return
583	        \c B_OK.
584
585	\see StartWatchingAll(BMessenger), StopWatching(BMessenger, uint32)
586
587	\since BeOS R5
588*/
589
590
591/*!
592	\fn status_t BHandler::StartWatchingAll(BMessenger target)
593	\brief Subscribe this handler to watch a \a target for all events.
594
595	This method performs the same task as StartWatching(BMessenger, uint32),
596	but it will subscribe to all the state changes the \a target knows. 
597
598	\see StartWatching(BMessenger, uint32), StopWatchingAll(BMessenger)
599
600	\since BeOS R5
601*/
602
603
604/*!
605	\fn status_t BHandler::StopWatching(BMessenger target, uint32 what)
606	\brief Unsubscribe this handler from watching a specific state.
607
608	This method will unsubscribe this handler from watching a specific event
609	in a \a target.
610
611	\see StartWatching(BMessenger, uint32)
612
613	\since BeOS R5
614*/
615
616
617/*!
618	\fn status_t BHandler::StopWatchingAll(BMessenger target)
619	\brief Unsubscribe this handler from watching all states.
620
621	This method will unsubscribe the \a target from watching all state changes.
622
623	\see StartWatchingAll(BMessenger)
624
625	\since BeOS R5
626*/
627
628
629/*!
630	\fn status_t BHandler::StartWatching(BHandler* observer, uint32 what)
631	\brief Subscribe an \a observer for a specific state change of this handler.
632
633	Use this method to subscribe observers to watch this handler. State changes
634	of this handler that match the \a what argument, will be sent.
635
636\code
637// Handler B wants to observe Handler A
638BHandler A, B;
639
640A.StartWatching(&B, kNetworkConnection);
641\endcode
642
643	Since pointers to handlers can only
644	exist in the local namespace, have a look at
645	StartWatching(BMessenger, uint32) for inter-team watching. 
646
647	\param observer The observer for this handler.
648	\param what The state that needs to be watched.
649	\return During the call of this method, a notification will be transmitted
650		using the \a observer. If this works, then this method will return
651		\c B_OK.
652
653	\see StartWatchingAll(BHandler*), StopWatching(BHandler*, uint32)	
654
655	\since BeOS R5
656*/
657
658
659/*!
660	\fn status_t BHandler::StartWatchingAll(BHandler* observer)
661	\brief Subscribe an \a observer for a all state changes.
662
663	This method performs the same task as StartWatching(BHandler, uint32),
664	but it will subscribe the \a observer to all the state changes this handler
665	tracks.
666
667	\see StartWatching(BHandler*, uint32), StopWatchingAll(BHandler*)	
668
669	\since BeOS R5
670*/
671
672
673/*!
674	\fn status_t BHandler::StopWatching(BHandler* handler, uint32 what)
675	\brief Unsubscribe an observer from watching a specific state.
676
677	This method will unsubscribe the \a handler from watching a specific event.
678
679	\see StartWatching(BHandler*, uint32)
680
681	\since BeOS R5
682*/
683
684
685/*!
686	\fn status_t BHandler::StopWatchingAll(BHandler* handler)
687	\brief Unsubscribe an observer from watching all states.
688
689	This method will unsubscribe the \a handler from watching all state changes.
690
691	\see StartWatchingAll(BHandler*)
692
693	\since BeOS R5
694*/
695
696
697//! @}
698
699
700///// State changes /////
701
702
703/*!
704	\name Emitting State Changes
705
706	If your handler functions as a state machine, and it has observers (which
707	subscribed using the StartWatching() method), you can emit these state
708	changes.
709*/
710
711
712//! @{
713
714
715/*!
716	\fn void BHandler::SendNotices(uint32 what, const BMessage* notice)
717	\brief Emit a state change to the observers.
718
719	The actual state (specified by \a what) will not be transmitted. This is
720	merely for internal bookkeeping. It is not entirely unimaginable that you
721	still want to inform the observers of what actually took place. You can
722	use the \a msg to transmit this, and any other data you want. Note that
723	the message will be copied and slightly altered: the \c what member of the
724	message will be \c B_OBSERVER_NOTICE_CHANGE, and the \c what constant you
725	specified will be stored in the #B_OBSERVE_ORIGINAL_WHAT label.
726
727	\param what The identifier of the state.
728	\param notice Any data associated with the state change. You retain
729	       ownership of this data, so make sure you dispose it when you are
730	       done.
731
732	\since BeOS R5
733*/
734
735
736/*!
737	\fn bool BHandler::IsWatched() const
738	\brief Check if there are any observers watching this handler.
739
740	\since BeOS R5
741*/
742
743
744//! @}
745