root/lang/cplusplus/i3/src/mol/include/mol/Module.h @ 15419

Revision 15419, 3.2 kB (checked in by saturday06, 5 years ago)

make windows-locale

Line 
1#pragma once
2#include "Mol.h"
3
4namespace mol
5{
6
7template <class T, int V = 0
8    + (sizeof(T) <= 16   ? 0:1)
9    + (sizeof(T) <= 32   ? 0:1)
10    + (sizeof(T) <= 64   ? 0:1)
11    + (sizeof(T) <= 192  ? 0:1)
12    + (sizeof(T) <= 1024 ? 0:1)
13> struct PoolSizeSelector {};
14
15template <class T> struct PoolSizeSelector<T, 0> {enum { SIZE = 16 };};
16template <class T> struct PoolSizeSelector<T, 1> {enum { SIZE = 32 };};
17template <class T> struct PoolSizeSelector<T, 2> {enum { SIZE = 64 };};
18template <class T> struct PoolSizeSelector<T, 3> {enum { SIZE = 192 };};
19template <class T> struct PoolSizeSelector<T, 4> {enum { SIZE = 1024 };};
20
21}
22
23namespace mol
24{
25
26template <typename Child>
27class Module : public boost::noncopyable
28{
29    Child& getChild() {
30        return *static_cast<Child*>(this);
31    }
32
33    class EventBase : public boost::intrusive::list_base_hook<>, public boost::noncopyable
34    {
35    public:
36        void (*execute)(void* list, void* target);
37    };
38
39    class EventList : public boost::noncopyable
40    {
41        boost::intrusive::list<EventBase> l;
42        boost::details::pool::default_mutex m;
43            typedef boost::details::pool::guard<boost::details::pool::default_mutex> guard;
44    public:
45        void createUI() {
46            mol_abort();
47        }
48        void push(EventBase& e) {
49                guard g(m);
50            l.push_back(e);
51        }
52
53        void pop() {
54                guard g(m);
55            l.pop_front();
56        }
57
58        EventBase* top() {                                                                                                         
59                guard g(m);
60            if (l.size() == 0) {
61                return NULL;
62            }
63            return &l.front();
64        }
65    };
66
67    template <typename T>
68    class Event : public EventBase
69    {
70    public:
71        T data;
72    };
73
74    friend class Module_test;
75    EventList list;
76
77private:
78    bool repost;
79public:
80    void repostEvent() {
81        repost = true;
82    }
83
84    template <typename Data, typename Target>
85    static void dispatcher(void* list_, void* target_)
86    {
87        // XXX type safety??
88        EventList& list = *static_cast<EventList*>(list_);
89        Target& target = *static_cast<Target*>(target_);
90
91        Event<Data>* event = static_cast<Event<Data>*>(list.top());
92        if (!event) {
93            return;
94        }
95        list.pop();
96
97        // �C�����C�����ŏ���򂪏���邩��
98        target.repost = false;
99        target.getChild().execute(event->data);
100        if (!target.repost) {
101            // �폜
102            boost::singleton_pool<char, PoolSizeSelector<Event<Data> >::SIZE>::free(event);
103        } else {
104                target.repost = false;
105            // �����g��
106            list.push(*event);
107        }
108    }
109public:
110    template <typename T>
111    void post(const T& event)
112    {
113        void* p = boost::singleton_pool<char, PoolSizeSelector<Event<T> >::SIZE>::malloc();
114        if (p == NULL) {
115            // XXX
116            return;
117        }
118
119        Event<T>* e = new(p) Event<T>;
120        e->data = event;
121        e->execute = dispatcher<T, Child>;
122
123        list.push(*e);
124    }
125
126    void execute_front()
127    {
128        list.top()->execute((void*)&list,this);
129    }
130};
131}
Note: See TracBrowser for help on using the browser.