updated the interface based on discussions with Parker
diff --git a/aos/common/queue.h b/aos/common/queue.h
index 77fdf0d..f1d9f82 100644
--- a/aos/common/queue.h
+++ b/aos/common/queue.h
@@ -11,6 +11,9 @@
 
 #include "aos/common/time.h"
 #include "aos/common/macros.h"
+#ifndef SWIG
+#include "aos/common/queue_types.h"
+#endif  // SWIG
 #ifndef USE_UNSAFE
 #include "aos/linux_code/ipc_lib/queue.h"
 #endif  // USE_UNSAFE
@@ -18,54 +21,6 @@
 
 namespace aos {
 
-#ifndef SWIG
-
-// Prints the value from 1 message field into output.
-// output is where to write the text representation.
-// output_bytes should point to the number of bytes available to write in
-// output. It will be changed to the number of bytes that were actually written.
-// input is where to read the data in from.
-// input_bytes should point to the number of bytes available to read from input.
-// It will be changed to the number of bytes that were actually read.
-// type is the ID of a type to print. It must be a primitive type.
-//
-// The implementation of this is generated by the ruby code.
-// TODO(brians): Actually do that.
-bool PrintField(char *output, size_t *output_bytes, void *input,
-                size_t *input_bytes, uint32_t type);
-
-// The type IDs this uses are 2 parts: a 16 bit size and a 16 bit hash. Sizes
-// for primitive types are stored with 8192 added.
-//
-// Serializing/deserializing includes all of the fields too.
-struct MessageType {
-  struct Field {
-    uint32_t type;
-    const char *name;
-  };
-
-  ~MessageType() {
-    for (int i = 0; i < number_fields; ++i) {
-      delete fields[i];
-    }
-  }
-
-  // Returns -1 for error.
-  ssize_t Serialize(char *buffer, size_t max_bytes) const;
-  // bytes should start out as the number of bytes available in buffer and gets
-  // set to the number actually read before returning.
-  // Returns a new instance allocated with new or NULL for error.
-  static MessageType *Deserialize(const char *buffer, size_t *bytes);
-
-  uint32_t id;
-  const char *name;
-
-  int number_fields;
-  const Field *fields[];
-};
-
-#endif  // SWIG
-
 // This class is a base class for all messages sent over queues.
 class Message {
  public:
diff --git a/aos/common/queue_types.cc b/aos/common/queue_types.cc
new file mode 100644
index 0000000..9ffef25
--- /dev/null
+++ b/aos/common/queue_types.cc
@@ -0,0 +1,6 @@
+#include "aos/common/queue_types.h"
+
+namespace aos {
+
+
+}  // namespace aos
diff --git a/aos/common/queue_types.h b/aos/common/queue_types.h
new file mode 100644
index 0000000..51455cd
--- /dev/null
+++ b/aos/common/queue_types.h
@@ -0,0 +1,72 @@
+#ifndef AOS_COMMON_QUEUE_TYPES_H_
+#define AOS_COMMON_QUEUE_TYPES_H_
+
+#include <sys/types.h>
+#include <stdint.h>
+
+namespace aos {
+
+// Prints the value from 1 message field into output.
+// output is where to write the text representation.
+// output_bytes should point to the number of bytes available to write in
+// output. It will be changed to the number of bytes that were actually written.
+// input is where to read the data in from.
+// input_bytes should point to the number of bytes available to read from input.
+// It will be changed to the number of bytes that were actually read.
+// type is the ID of a type to print. It must be a primitive type.
+//
+// The implementation of this is generated by the ruby code.
+// TODO(brians): Actually do that.
+bool PrintField(char *output, size_t *output_bytes, void *input,
+                size_t *input_bytes, uint32_t type);
+
+// The type IDs this uses are 2 parts: a 16 bit size and a 16 bit hash. Sizes
+// for primitive types are stored with 8192 added.
+//
+// Serializing/deserializing includes all of the fields too.
+struct MessageType {
+  struct Field {
+    // The type ID for the type of this field.
+    uint32_t type;
+    const char *name;
+  };
+
+  ~MessageType() {
+    for (int i = 0; i < number_fields; ++i) {
+      delete fields[i];
+    }
+  }
+
+  // Returns -1 for error.
+  ssize_t Serialize(char *buffer, size_t max_bytes) const;
+  // bytes should start out as the number of bytes available in buffer and gets
+  // set to the number actually read before returning.
+  // Returns a new instance allocated with new or NULL for error.
+  static MessageType *Deserialize(const char *buffer, size_t *bytes);
+
+  static bool IsPrimitive(uint32_t type_id) {
+    return (type_id & 0xFFFF) >= 8192;
+  }
+
+  // The type ID for this.
+  uint32_t id;
+  const char *name;
+
+  int number_fields;
+  const Field **fields;
+};
+
+namespace type_cache {
+
+// Makes sure a type is in the type cache. This will store a reference to type.
+void Add(const MessageType &type);
+// Retrieves a type from the type cache or shm. LOG(FATAL)s if it can't find it.
+const MessageType &Get(uint32_t type_id);
+// Makes sure a type is in the list in shm. Add must have already been called
+// for type.
+void AddShm(uint32_t type_id);
+
+}  // namespace type_cache
+}  // namespace aos
+
+#endif  // AOS_COMMON_QUEUE_TYPES_H_