first check-in of feisty meow codebase. many things broken still due to recent
[feisty_meow.git] / octopi / library / synchronic / synchronizable.h
1 #ifndef SYNCHRONIZABLE_CLASS
2 #define SYNCHRONIZABLE_CLASS
3
4 /*
5 *  Name   : synchronizable
6 *  Author : Chris Koeritz
7 ***
8 * Copyright (c) 2002-$now By Author.  This program is free software; you can  *
9 * redistribute it and/or modify it under the terms of the GNU General Public  *
10 * License as published by the Free Software Foundation; either version 2 of   *
11 * the License or (at your option) any later version.  This is online at:      *
12 *     http://www.fsf.org/copyleft/gpl.html                                    *
13 * Please send any updates to: fred@gruntose.com                               *
14 \*****************************************************************************/
15
16 #include <octopus/infoton.h>
17 #include <timely/time_stamp.h>
18
19 namespace synchronic {
20
21 //! Encapsulates all of the attributes known for an object.
22 /*!
23   This relies on the naming scheme for infotons, so objects are unique
24   only so far as their classifiers are different.  For example, if the objects
25   are to be differentiated by the computer that they run on, then some
26   unique form of that computer's name should be used as one of the components
27   of the classifier.  Each object can hold a variety of information which
28   is not defined here.  Instead, we require the merge() method that
29   performs object specific reconciliation when an update arrives.
30 */
31
32 class synchronizable : public octopi::infoton
33 {
34 public:
35   enum modifications {
36     ADDED,     // the object is new.
37     CHANGED,   // the object has been modified.
38     DELETED    // the object got removed.
39   };
40
41   modifications _mod;
42     // the type of change that has happened for this object.  the derived
43     // class must pack this information in the derived pack() method and
44     // retrieve the modification info in unpack().  there are helper functions
45     // pack_mod() and unpack_mod() to automate that responsibility.
46
47   timely::time_stamp _updated;
48     // when this information was last updated.  this should not be packed,
49     // since it is only locally relevant.
50
51   synchronizable(const structures::string_array &object_id) : infoton(object_id) {}
52     // constructs the base portion of an attribute bundle for an object with
53     // the "object_id".  the "object_id" must follow the rules for infoton
54     // classifiers.  the last string in the object id is the list-unique
55     // identifier for this set of attributes.
56
57   enum outcomes {
58     OKAY = basis::common::OKAY,  // the operation completed successfully.
59     BAD_TYPE = basis::common::BAD_TYPE,  // provided object had an incompatible type.
60     EMPTY = basis::common::IS_EMPTY  // the merge resulted in clearing this entry.
61   };
62
63   // helper functions for packing the modification information.
64   void pack_mod(basis::byte_array &packed_form) const;
65   bool unpack_mod(basis::byte_array &packed_form);
66   int packed_mod_size() const { return sizeof(int); }
67     //!< returns the size of the packed modifier.
68
69   virtual basis::outcome merge(const synchronizable &to_merge) = 0;
70     // overwrites any attributes in "this" bundle with the contents found
71     // in "to_merge".  this can fail if the object types are different.
72
73   virtual basis::astring text_form() const = 0;
74     // provides a visual form of the data held in this bundle.
75
76   // promote requirements of the infoton to derived objects.
77   virtual void pack(basis::byte_array &packed_form) const = 0;
78   virtual bool unpack(basis::byte_array &packed_form) = 0;
79   virtual clonable *clone() const = 0;
80   virtual int packed_size() const = 0;
81 };
82
83 //////////////
84
85 // implementations.
86
87 void synchronizable::pack_mod(basis::byte_array &packed_form) const
88 { structures::attach(packed_form, int(_mod)); }
89
90 bool synchronizable::unpack_mod(basis::byte_array &packed_form)
91 {
92   int temp;
93   if (!structures::detach(packed_form, temp)) return false;
94   _mod = (modifications)temp;
95   return true;
96 }
97
98 } //namespace.
99
100 #endif
101