Guest User

Layout Archiving in Haiku

a guest
Apr 8th, 2010
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. My plan for layout archiving focuses mainly on a few related objects, which manage the [de]archiving process:
  3. I will name these classes as I go along, but theses names are not final at all. Also, although this greatly resembles c++ code, its only purpose is to illustrate my ideas, it would make a compiler grumpy.
  5. //important classes
  6. class LayoutArchiveManager;
  7. class LayoutArchiver;
  8. class LayoutDeArchiver;
  9. class BPrivate::LayoutArchiverPrivate;
  10. class Bprivate::LayoutDeArchiverPrivate;
  11. class SomeKindOfVector;
  14. class LayoutArchiveManager
  15. {
  16. public:
  18. //returns the new sessionToken
  19. int NewArchivingSession(BMessage* topLevelArchive);
  20. LayoutArchiver GetArchiver(int sessionToken);//or maybe (Bmessage* archive)
  22. //also returns a sessionToken, but it is fished out from topLevelArchive
  23. int NewDeArchivingSession(BMessage* topLevelArchive);
  24. LayoutDeArchiver GetDeArchiver(int sessiontoken );//or maybe (Bmessage* archive)
  25. //same idea but for de-archiving
  27. ...
  28. private:
  29. friend class LayoutArchiver;
  30. friend class LayoutDeArchiver
  31. void DereferenceArchiver(int token);
  32. void DereferenceDeArchiver(int token);
  33. };
  34. extern LayoutArchiveManager *gLayoutArchiveManager
  36. class LayoutArchiver
  37. {
  38. public:
  39. int GetToken(BView *subject);
  40. int GetToken(BLayoutItem *subject);
  41. //creates a token that can be used later in dearchiving
  43. /* these methods assign a token to the object, and add some info to the archive. They should be called before GetToken() is called, e.g. to allow children view to get the token of their parent*/
  44. void RegisterArchive(BMessage* archive, Bview* );
  45. void RegisterArchive(BMessage* archive, BlayoutItem* );
  47. ~LayoutArchiver() { gLayoutArchiveManager->DereferenceArchiver(fArchiver->Token()); }
  48. private:
  49. friend class LayoutArchiveManager;
  50. LayoutArchiver(LayoutArchiverPrivate* archiver);
  51. private:
  52. LayoutArchiverPrivate* fArchiverPrivate;
  53. };
  56. class LayoutArchiverPrivate
  57. {
  58. private:
  59. friend class LayoutArchiveManager;
  60. LayoutArchiverPrivate();
  61. int references;
  62. private:
  63. friend class LayoutArchiver;
  64. int GetToken(BView* subject);
  65. int GetToken(BLayoutItem* subject);
  66. int Token();
  67. private:
  68. someKindOfVector<BView*>* fViews;
  69. someKindOfVector<BLayoutItem*>* fLayoutItems;
  70. Bmessage* fTopArchive;
  71. int fSessionToken;
  72. };
  74. So, that is about what will be used in archiving. As you can see, there is a global object that oversees any and all archiving. The LayoutArchivers that it passes out allow us to implement reference counting so that as they go out of scope, gLayoutArchiveManager will decrement LayoutArchiverPrivate::references for the appropriate LayoutArchiverPrivate. When a Bview wishes to archive it's children, it must simply add a field into the Bmessage that their child will be archiving in which holds the token for this archiving session. This token will be used later to ask gLayoutArchiveManager for a LayoutDeArchiver. As an object (either Bview or BlayoutItem) is archiving itself, it notes which tokens represent the other objects it references in its archive.
  76. So, that should give anyone reading this the gist of the archiving process, but that is only half the story isn't it? So, on to dearchiving!
  78. The de-archiving process is fairly simillar, but is also a bit more complex. We now have, instead of RegisterArchive, ClaimToken, which works in a very similar fashion. It is important to note that between an object calling either of these methods on their Layout[De]Archiver and finishing their constructer, some methods should not be called. What I might do is make two more classes which act as proxies of Bview and BlayoutItem to enforce this. Instead of GetView() returning a Bview*, it would return one of these proxies for example. Such a class might also replace Bview* Parent() with int Parent() (return the parent's token), to make life a little easier. The type of methods restricted would be things like Parent(), ChildAt() etc. Anyway, the most important method of the dearchiving process would be LayoutDeArchiverPrivate::Get...(), in the event an object has not yet been constructed, this method would recursively search through fArchive, find the appropriate Bmessage archive, have the object de-archive itself and then return the newly created object. Alternatively, the different messages could be unpacked into SomeKindOfVector and accessed when the LayoutDeArchiverPrivate is constructed, which would be faster.
  80. class LayoutDeArchiver
  81. {
  82. public:
  83. //if the appropriate Object has already been built, a pointer is returned, otherwise, it is built
  84. Bview* GetView(int token);
  85. BLayoutItem* GetLayoutItem(int token);
  87. /*during an object's construction, and before it calls Get...(), it will call ClaimToken(), although the object will not yet be fully constructed, it will be constructed enough :D*/
  88. void ClaimToken(int token, Bview* subject);
  89. void ClaimToken(int token, BlayoutItem* subject);
  91. ~LayoutDeArchiver()
  92. {gLayoutArchiveManager->DereferenceDeArchiver(fDeArchiver->Token()); };
  94. private:
  95. friend class LayoutArchiveManager;
  96. LayoutDeArchiver(LayoutDeArchiverPrivate* privateDearchiver);
  98. private:
  99. LayoutDeArchiverPrivate* fDeArchiver;
  100. };
  103. class LayoutDeArchiverPrivate{
  104. private:
  105. friend class LayoutArchiverManager;
  106. LayoutDeArchiverPrivate(BMessage* archive);
  107. int references;
  109. private:
  110. friend class LayoutArchiver;
  111. Bview* GetView(int token);
  112. BLayoutItem* GetLayoutItem(int token);
  113. void ClaimToken(int token, Bview* subject);
  114. void ClaimToken(int token, BlayoutItem* subject);
  116. private:
  117. someKindOfVector<BView*>* fViews;
  118. someKindOfVector<BLayoutItem*>* fLayoutItems;
  119. Bmessage* fTopArchive;
  120. int fSessionToken;
  121. };
  123. A note on thread safety: I would like to make this process thread safe, although large chunks would still have to happen serially, some actons could probably be parallelized.
  125. Alright, I think that covers it, If I've missed anything, please e-mail me and I will update this. Hopefully this answers any questions on the subject!
  127. One more note: as I said earlier, the names of classes, methods etc. May change, as may the actual method signatures. However, the general idea behind these classes should remain relatively static. For example, I will probably create a base class for LayoutArchiverPrivate and LayoutDeArchiverPrivate to share, as they have alot in common.
  129. Thanks for reading!
  130. Alex
RAW Paste Data