xitemnode.h
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 #ifndef XITEMNODE_H_
15 #define XITEMNODE_H_
16 
17 #include "xnode.h"
18 #include "xlistnode.h"
19 
20 //! Posses a pointer to a member of a list
21 class DECLSPEC_KAME XItemNodeBase : public XValueNodeBase {
22 public:
23  explicit XItemNodeBase(const char *name, bool runtime = false, bool auto_set_any = false);
24  virtual ~XItemNodeBase() = default;
25 
26  struct Item { XString name, label; };
27  virtual std::vector<Item> itemStrings(const Snapshot &shot_of_list) const = 0;
28 
29  bool autoSetAny() const {return !!m_lsnTryAutoSet;}
30 
31  struct DECLSPEC_KAME Payload : public XValueNodeBase::Payload {
33  struct ListChangeEvent {
34  ListChangeEvent(const Snapshot &s, XItemNodeBase *e) : shot_of_list(s), emitter(e) {}
35  Snapshot shot_of_list;
36  XItemNodeBase *emitter;
37  };
38  Talker<ListChangeEvent> &onListChanged() {return m_tlkOnListChanged;}
39  const Talker<ListChangeEvent> &onListChanged() const {return m_tlkOnListChanged;}
40  private:
41  TalkerSingleton<ListChangeEvent> m_tlkOnListChanged;
42  };
43 private:
44  shared_ptr<XListener> m_lsnTryAutoSet;
45  void onTryAutoSet(const Snapshot &shot, const Payload::ListChangeEvent &e);
46 };
47 
48 DECLSPEC_KAME void
49 xpointeritemnode_throwConversionError_();
50 
51 template <class TL>
53 public:
54  XPointerItemNode(const char *name, bool runtime, Transaction &tr_list,
55  const shared_ptr<TL> &list, bool auto_set_any = false)
56  : XItemNodeBase(name, runtime, auto_set_any), m_list(list) {
57  m_lsnOnItemReleased = tr_list[ *list].onRelease().connect( *this, &XPointerItemNode<TL>::onItemReleased);
58  m_lsnOnListChanged = tr_list[ *list].onListChanged().connect( *this, &XPointerItemNode<TL>::lsnOnListChanged);
59  }
60  virtual ~XPointerItemNode() = default;
61 
62  struct Payload : public XItemNodeBase::Payload {
63  operator shared_ptr<XNode>() const { return m_var.lock();}
64  virtual XString to_str() const override {
65  shared_ptr<XNode> node( *this);
66  if(node)
67  return node->getLabel();
68  else
69  return XString();
70  }
71  Payload &operator=(const shared_ptr<XNode> &t) {
72  m_var = t;
73  tr().mark(onValueChanged(), static_cast<XValueNodeBase*>( &node()));
74  return *this;
75  }
76  protected:
77  virtual void str_(const XString &var) override {
78  if(var.empty()) {
79  *this = shared_ptr<XNode>();
80  return;
81  }
82  if(auto list = static_cast<const XPointerItemNode&>(node()).m_list.lock()) {
83  Snapshot shot( *list);
84  if(shot.size()) {
85  for(auto it = shot.list()->begin(); it != shot.list()->end(); ++it) {
86  if(( *it)->getLabel() == var) {
87  *this = *it;
88  return;
89  }
90  }
91  }
92  }
93  xpointeritemnode_throwConversionError_();
94  }
95  weak_ptr<XNode> m_var;
96  };
97 private:
98  void onItemReleased(const Snapshot& /*shot*/, const XListNodeBase::Payload::ReleaseEvent &e) {
99  for(Snapshot shot( *this);;) {
100  if(e.released != (shared_ptr<XNode>)shot[ *this])
101  break;
102  Transaction tr(shot);
103  tr[ *this] = shared_ptr<XNode>();
104  if(tr.commit()) break;
105  }
106  }
107  void lsnOnListChanged(const Snapshot& shot, XListNodeBase* node) {
108  if(auto list = m_list.lock()) {
109  assert(node == list.get());
110  typename Payload::ListChangeEvent e(shot, this);
111  Snapshot( *this).talk(( **this)->onListChanged(), std::move(e));
112  }
113  }
114  shared_ptr<XListener> m_lsnOnItemReleased, m_lsnOnListChanged;
115 protected:
116  weak_ptr<TL> m_list;
117 };
118 
119 template <class TL, class... VT>
120 class XItemNode;
121 
122 template <class TL>
123 class XItemNode<TL> : public XPointerItemNode<TL> {
124 protected:
125  XItemNode(const char *name, bool runtime, Transaction &tr_list,
126  const shared_ptr<TL> &list, bool auto_set_any = false)
127  : XPointerItemNode<TL>(name, runtime, tr_list, list, auto_set_any) {
128  }
129  virtual ~XItemNode() = default;
130  virtual std::vector<XItemNodeBase::Item> itemStrings(const Snapshot &) const override {
131  return std::vector<XItemNodeBase::Item>();
132  }
133 };
134 
135 //! A pointer to a XListNode TL, T1 (and VT) are value types
136 //! template <class TL, class... VT>
137 template <class TL, class T1, class... VT>
138 class XItemNode<TL, T1, VT...> : public XItemNode<TL, VT...> {
139 public:
140  XItemNode(const char *name, bool runtime, Transaction &tr_list,
141  const shared_ptr<TL> &list, bool auto_set_any = false)
142  : XItemNode<TL, VT...>(name, runtime, tr_list, list, auto_set_any) {
143  }
144  virtual ~XItemNode() = default;
145 
146  struct Payload : public XItemNode<TL, VT...>::Payload {
147  Payload() : XItemNode<TL, VT...>::Payload() {}
148  operator shared_ptr<T1>() const {
149  return dynamic_pointer_cast<T1>(shared_ptr<XNode>( *this));
150  }
151  Payload &operator=(const shared_ptr<XNode> &t) {
153  return *this;
154  }
155  };
156 
157  virtual std::vector<XItemNodeBase::Item> itemStrings(const Snapshot &shot) const override {
158  auto items = this->XItemNode<TL, VT...>::itemStrings(shot);
159  if(auto list = this->m_list.lock()) {
160  if(shot.size(list)) {
161  for(auto it = shot.list(list)->begin(); it != shot.list(list)->end(); ++it) {
162  if(dynamic_pointer_cast<T1>( *it)) {
163  XItemNodeBase::Item item;
164  item.name = ( *it)->getName();
165  item.label = ( *it)->getLabel();
166  items.push_back(std::move(item));
167  }
168  }
169  }
170  }
171  return std::move(items);
172  }
173 };
174 
175 //! Contains strings, value is one of strings
176 class DECLSPEC_KAME XComboNode : public XItemNodeBase {
177 public:
178  explicit XComboNode(const char *name, bool runtime = false, bool auto_set_any = false);
179  virtual ~XComboNode() = default;
180 
181  virtual std::vector<XItemNodeBase::Item> itemStrings(const Snapshot &shot) const override {
182  return shot[ *this].itemStrings();
183  }
184 
185  struct DECLSPEC_KAME Payload : public XItemNodeBase::Payload {
186  Payload() : XItemNodeBase::Payload(), m_strings(std::make_shared<std::deque<XString>>()),
187  m_var(std::pair<XString, int>("", -1)) {}
188  void add(const XString &str);
189  void add(std::initializer_list<XString> strlist) {for(auto &&x: strlist){ add(x);}}
190  void clear();
191  operator int() const { return m_var.second;}
192  virtual XString to_str() const override { return m_var.first;}
193  Payload &operator=(int t);
194  Payload &operator=(const XString &);
195  virtual std::vector<XItemNodeBase::Item> itemStrings() const;
196  protected:
197  virtual void str_(const XString &) override;
198  private:
199  shared_ptr<std::deque<XString> > m_strings;
200  std::pair<XString, int> m_var;
201  };
202 };
203 
204 #endif /*XITEMNODE_H_*/

Generated for KAME4 by  doxygen 1.8.3