InDesign SDK  20.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
CM2MMessageListener.h
1 //========================================================================================
2 //
3 // $File$
4 //
5 // Owner: dwaterfa
6 //
7 // $Author$
8 //
9 // $DateTime$
10 //
11 // $Revision$
12 //
13 // $Change$
14 //
15 // ADOBE CONFIDENTIAL
16 //
17 // Copyright 1997-2010 Adobe Systems Incorporated. All rights reserved.
18 //
19 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance
20 // with the terms of the Adobe license agreement accompanying it. If you have received
21 // this file from a source other than Adobe, then your use, modification, or
22 // distribution of it requires the prior written permission of Adobe.
23 //
24 //========================================================================================
25 
26 
27 #ifndef __CM2MMessageListener__
28 #define __CM2MMessageListener__
29 
30 #include "IM2MMessageListener.h"
31 #include "IClassInfo.h"
32 #include "IObjectModel.h"
33 #include "IPMStream.h"
34 
35 
36 
279 class CM2MMessageListener : public CPMUnknown<IM2MMessageListener>
280 {
281 public:
286  class myPrivateData : public PrivateData
287  {
288  static const int32 kPreCheckValue = 101363;
289  static const int32 kPostCheckValue = 101364;
290 
291  public:
300  virtual void Message(IM2MMessageListener::MessageHelper& helper) = 0;
301 
309  virtual void SubListenerSnapshotReadWrite(IPMStream* stream) = 0;
310 
316  virtual void SnapshotReadWrite(IPMStream* stream)
317  {
318  // This helps catch override errors. See SnapshotRead() below.
319  int32 pre_checkValue = kPreCheckValue;
320  stream->XferInt32(pre_checkValue);
321 
322  ASSERT_MSG((stream->IsWriting()) ||
323  (pre_checkValue == kPreCheckValue), "CM2MMessageListener::SnapshotReadWrite() - a sub-listener has overriden CM2MMessageListener::myPrivateData::SnapshotReadWrite(). Implement only CM2MMessageListener::myPrivateData::SubListenerSnapshotReadWrite()");
324 
325  // Write out the index of the SubListener who created the data.
326  stream->XferInt32(fSubListenerIndex);
327  ASSERT(fSubListenerIndex >= 0);
328 
329  //
330  // Let the SubListener snapshot. If they don't have any data
331  // that ever changes between construction and the call to
332  // Validate() then they don't have to do anything.
333  //
335 
336  // This helps catch unfinished read errors. See
337  // SnapshotRead() below.
338  int32 post_checkValue = kPostCheckValue;
339  stream->XferInt32(post_checkValue);
340 
341  ASSERT_MSG((stream->IsWriting()) ||
342  (post_checkValue == kPostCheckValue), "CM2MMessageListener::SnapshotReadWrite() - a sub-listener has a sub-listener has not read all that it had previously written");
343 
344  }
345 
350  virtual void Abandon(bool16)
351  { }
352 
357  void SetSubListenerIndex(int32 n)
358  { fSubListenerIndex = n; }
359 
360  private:
361  int32 fSubListenerIndex;
362 
363  };
364 
365 protected:
371  virtual int32 GetSubListenerCount() const = 0;
372 
379  typedef bool16 (*funcGetCanHandle)(const IClassInfo* cInfo);
380 
387  virtual funcGetCanHandle GetNthSubListenerGetCanHandle(int32 n) const = 0;
388 
401  typedef void (*funcGetMessages)(const PMIID*& targetM, uint32& targetMSize,
402  const PMIID*& ancestorM, uint32& ancestorMSize,
403  const PMIID*& descendentM, uint32& descendentMSize,
404  const PMIID*& unrelatedM, uint32& unrelatedMSize);
405 
412  virtual funcGetMessages GetNthSubListenerGetMessages(int32 n) const = 0;
413 
422  typedef myPrivateData* (*funcCreateFor)(IM2MMessageListener::MessageHelper& helper) ;
423 
430  virtual funcCreateFor GetNthSubListenerCreateFor(int32 n) const = 0;
431 
441  typedef myPrivateData* (*funcSnapshotRead)(const UIDRef& targetRef,
442  IPMStream* inStream);
443 
450  virtual funcSnapshotRead GetNthSubListenerSnapshotRead(int32 n) const = 0;
451 
461 
465  virtual void GetMessagesFor(const IClassInfo* cInfo,
466  const PMIID*& targetM,
467  uint32& targetMSize,
468  const PMIID*& ancestorM,
469  uint32& ancestorMSize,
470  const PMIID*& descendentM,
471  uint32& descendentMSize,
472  const PMIID*& unrelatedM,
473  uint32& unrelatedMSize) const
474  {
475  ASSERT((targetM == nil) && (targetMSize == 0));
476  ASSERT((ancestorM == nil) && (ancestorMSize == 0));
477  ASSERT((descendentM == nil) && (descendentMSize == 0));
478  ASSERT((unrelatedM == nil) && (unrelatedMSize == 0));
479 
480  const int32 slCount = GetSubListenerCount();
481 
482  for (int32 n = 0; n < slCount; n++)
483  {
484  //
485  // If GetCanHandle() function returns a match then we get the
486  // messages from the SubListener. First match wins.
487  //
488  if ((*GetNthSubListenerGetCanHandle(n))(cInfo))
489  {
490  (*GetNthSubListenerGetMessages(n))(targetM, targetMSize,
491  ancestorM, ancestorMSize,
492  descendentM, descendentMSize,
493  unrelatedM, unrelatedMSize);
494  break;
495  }
496  }
497  }
498 
502  virtual void Message(MessageHelper& helper, PrivateData* data)
503  {
504  myPrivateData* myData = (myPrivateData*)data;
505 
506  if (myData == nil)
507  {
508  //
509  // No private data defined. Try to create some. Extract an
510  // IClassInfo from the helper.
511  //
513  InterfacePtr<const IObjectModel> om(GetExecutionContextSession(), UseDefaultIID());
514  InterfacePtr<const IClassInfo> cInfo(om->QueryClassInfo(cu->GetClass()));
515  const int32 slCount = GetSubListenerCount();
516 
517  for (int32 n = 0; n < slCount; n++)
518  {
519  //
520  // If there is only one sub-listener, or the GetCanHandle()
521  // function returns a match then we let the SubListener create
522  // some private data. First match wins.
523  //
524  if ((slCount == 1) ||
525  ((*GetNthSubListenerGetCanHandle(n))(cInfo)))
526  {
527  //
528  // This SubListener get a chance to create. If it fails to
529  // do so we purposely DO NOT let another SubListener try.
530  //
531  // Because your Listener will ONLY be called with messages
532  // that it intested in the only reason to not create the
533  // private data might be some state of the object - but
534  // this is rare case.
535  //
536  myData = (*GetNthSubListenerCreateFor(n))(helper);
537  if (myData)
538  {
539  myData->SetSubListenerIndex(n);
540  helper.AddPrivateData(myData);
541  }
542  break;
543  }
544  }
545 
546  }
547 
548  if (myData)
549  {
550  myData->Message(helper);
551  }
552  }
553 
560  virtual PrivateData* SnapshotRead(const UIDRef& targetRef,
561  IPMStream* inStream)
562  {
563  int32 pre_checkValue, post_checkValue, n;
564 
565  // Did someone override SnapshotWrite() but not this? Hard to check
566  // the reverse case.
567  inStream->XferInt32(pre_checkValue);
568  ASSERT_MSG((pre_checkValue == 101363), "CM2MMessageListener::SnapshotRead() - a sub-listener has overriden CM2MMessageListener::myPrivateData::SnapshotReadWrite(). Implement only CM2MMessageListener::myPrivateData::SubListenerSnapshotReadWrite()");
569 
570  // Get the SubListener index.
571  inStream->XferInt32(n);
572  ASSERT((n >= 0) && (n < GetSubListenerCount()));
573 
574  // Call the SubListener's SnapshotRead() method.
575  myPrivateData* myData = (*GetNthSubListenerSnapshotRead(n))(targetRef, inStream);
576  myData->SetSubListenerIndex(n);
577 
578  // Make sure everything which was expected to be
579  // read was read.
580  inStream->XferInt32(post_checkValue);
581  ASSERT_MSG((post_checkValue == 101364), "CM2MMessageListener::SnapshotRead() - a sub-listener has not read all that it had previously written");
582 
583  return myData;
584  }
585 
586 
587 };
588 
589 
590 #endif // __CM2MMessageListener__
591