Scopira 20080306

model.h

00001 
00002 /*
00003  *  Copyright (c) 2005    National Research Council
00004  *
00005  *  All rights reserved.
00006  *
00007  *  This material is confidential and proprietary information of
00008  *  National Research Council Canada ("Confidential Information").
00009  *  This Confidential Information may only be used and reproduced
00010  *  in accordance with the terms of the license agreement.
00011  *
00012  */
00013 
00014 #ifndef __INCLUDED_SCOPIRA_CORE_MODEL_H__
00015 #define __INCLUDED_SCOPIRA_CORE_MODEL_H__
00016 
00017 #include <assert.h>
00018 
00019 #include <vector>
00020 #include <map>
00021 
00022 #include <scopira/tool/object.h>
00023 #include <scopira/tool/reactor.h>
00024 #include <scopira/tool/iterator.h>
00025 #include <scopira/tool/export.h>
00026 
00027 namespace scopira
00028 {
00029   namespace core
00030   {
00031     class model_ptr_base;
00032     template <class T> class model_ptr;
00033 
00034     class model_i;
00035 
00036     class project_i;  //fwd
00037 
00038     class view_i;   // fwd
00039 
00041     typedef scopira::tool::iterator_g<model_i*> model_iterator;
00042   }
00043 }
00044 
00050 class scopira::core::model_ptr_base
00051 {
00052   protected:
00054     model_i *dm_model;
00055   public:
00057     model_ptr_base(void)
00058       : dm_model(0) { }
00059 
00061     model_i * const & get_model_ptr(void) const { return dm_model; }
00062 };
00063 
00069 template <class T> class scopira::core::model_ptr : public scopira::core::model_ptr_base
00070 {
00071   public:
00073     typedef T data_type;
00074 
00075   protected:
00077     view_i *dm_ins;
00079     T *dm_ptr;
00080 
00081   public:
00087     model_ptr(view_i *ins)
00088       : dm_ins(ins), dm_ptr(0) { assert(ins); }
00093     ~model_ptr()
00094       { set(0); }
00095 
00102     void set(T* o) {
00103       if (o) {
00104         o->add_ref();
00105         o->add_view(dm_ins);
00106       }
00107       if (dm_ptr) {
00108         dm_ptr->remove_view(dm_ins);
00109         dm_ptr->sub_ref();
00110       }
00111       dm_ptr = o;
00112       dm_model = o;   // double concrete magic [NOTE]
00113     }
00119     model_ptr & operator = (T *o)
00120       { set(o); return *this; }
00121 
00127     model_ptr & operator = (const model_ptr<T> &o)
00128       { set(o.dm_ptr); return *this; }
00134     bool operator == (const model_ptr<T> &rhs) const
00135       { return dm_ptr == rhs.dm_ptr; }
00141     bool operator != (const model_ptr<T> &rhs) const
00142       { return dm_ptr != rhs.dm_ptr; }
00148     bool operator < (const model_ptr<T> &rhs) const
00149       { return dm_ptr < rhs.dm_ptr; }
00150 
00156      //oflow_i & print(oflow_i &o) const
00157        //{ if (dm_ptr) dm_ptr->print(o); /*else o<<"(null)";*/ return o; }
00158 
00159     // do save and load like the above?
00160 
00166     T* get(void) const
00167       { return dm_ptr; }
00168     //T* get(void)
00169       //{ return dm_ptr; }
00170 
00176     T& ref(void) const
00177       { assert(dm_ptr); return *dm_ptr; }
00178     //T& ref(void)
00179       //{ assert(dm_ptr); return *dm_ptr; }
00180 
00186     T* operator ->(void) const
00187       { assert(dm_ptr); return dm_ptr; }
00188     //T* operator ->(void)
00189       //{ assert(dm_ptr); return dm_ptr; }
00190 
00196     T & operator *(void) const
00197       { assert(dm_ptr); return *dm_ptr; }
00198 
00204     bool is_null(void) const { return dm_ptr == 0; }
00205 };
00206 
00216 class scopira::core::model_i : public virtual scopira::tool::object
00217 {
00218   private:
00219     typedef std::vector<view_i*> view_list;
00220     typedef std::vector<scopira::tool::rename_reactor_i*> rename_list;
00221     typedef std::map<std::string, scopira::tool::count_ptr<model_i> > archive_cache_t;
00222 
00223     mutable view_list dm_views;
00224     mutable rename_list dm_rename_reactors;
00225     std::string dm_title;
00226     project_i *dm_owner;
00227 
00228     // mutable? mutex locked?
00229     archive_cache_t dm_archive_cache;
00230 
00231   public:
00233     SCOPIRA_EXPORT virtual bool load(scopira::tool::iobjflow_i& in);
00235     SCOPIRA_EXPORT virtual void save(scopira::tool::oobjflow_i& out) const;
00236 
00244     SCOPIRA_EXPORT virtual void set_title(const std::string &newtitle);
00245 
00251     virtual bool is_project(void) const { return false; }
00252 
00257     const std::string & get_title(void) const { return dm_title; }
00258 
00265     SCOPIRA_EXPORT void add_view(view_i *ins) const;
00271     SCOPIRA_EXPORT void remove_view(view_i *ins) const;
00280     SCOPIRA_EXPORT void notify_views(view_i *src);
00281 
00286     SCOPIRA_EXPORT void add_rename_reactor(tool::rename_reactor_i *r) const;
00291     SCOPIRA_EXPORT void remove_rename_reactor(tool::rename_reactor_i *r) const;
00292 
00301     SCOPIRA_EXPORT virtual void set_project(project_i *newowner);
00302 
00308     project_i * get_project(void) const { return dm_owner; }
00309 
00315     SCOPIRA_EXPORT void set_tagged_model(const std::string &name, model_i *what);
00316 
00325     template <class W>
00326       bool get_tagged_model(const std::string &name, W &out) {
00327         typedef typename W::data_type data_type;   // just to make sure they dont pass us a simple *T
00328         scopira::tool::count_ptr<scopira::core::model_i> mm;
00329         if (!get_tagged_model_impl(name, mm))
00330           return false;
00331         out = dynamic_cast<data_type*>(mm.get());
00332         return mm.is_null() || out.get();   // success is if the data was null OR the cast worked
00333       }
00334 
00335   protected:
00337     SCOPIRA_EXPORT model_i(void);
00339     SCOPIRA_EXPORT model_i(const std::string &title);
00341     SCOPIRA_EXPORT model_i(const model_i &src);
00343     SCOPIRA_EXPORT virtual ~model_i();
00344 
00345   private:
00347     SCOPIRA_EXPORT bool get_tagged_model_impl(const std::string &name,
00348         scopira::tool::count_ptr<scopira::core::model_i> &out);
00349 };
00350 
00351 #endif
00352