root/lang/objective-cplusplus/i3/trunk/src/mil/include/mil/ModuleCommon.h @ 34815

Revision 34815, 4.0 kB (checked in by saturday06, 4 years ago)

uc???????

Line 
1#pragma once
2
3#include "Thread.h"
4#include "Memory.h"
5
6namespace mil {
7
8class Tls {
9    struct Data {
10#ifdef MIL_GUI_WINDOWS
11        HWND hWndCache;
12#endif
13    } data[MIL_MAX_THREADS];
14    Data dummy;
15public:
16    Data& getData(unsigned int thread_id) {
17        if (thread_id >= MIL_MAX_THREADS) {
18            // Error
19            return dummy;
20        }
21        return data[thread_id];
22    }
23    void flush() {
24        for (size_t i = 0; i < _countof(data); i++) {
25#ifdef MIL_GUI_WINDOWS
26            data[i].hWndCache = NULL;
27#endif
28        }
29    }
30    const intptr_t thread_id;
31    pool::Producer producer;
32    pool::Consumer consumer;
33    Tls(intptr_t thread_id) : thread_id(thread_id), producer(thread_id) {
34        memset(&data, 0, sizeof(data));
35        memset(&dummy, 0, sizeof(dummy));
36    }
37};
38
39struct ExitEvent {
40};
41
42template <class T>
43struct IsExitEvent {
44    enum {
45        value = 0,
46    };
47};
48
49template <>
50struct IsExitEvent<ExitEvent> {
51    enum {
52        value = 1,
53    };
54};
55
56struct ModuleExecuteProxy {
57    template <class EventData, class Target>
58    static void execute_body(EventData& data, Target& target, typename EventData::IsReturnMemoryEvent) {
59        target.tls.producer.free(data.memory);
60    }
61
62    template <class EventData, class Target>
63    static void execute_body(EventData& data, Target& target, ...) {
64        MIL_MODULE_SUPER_CHILD_TYPE(Target)& o =
65            MIL_MODULE_GET_SUPER_CHILD(target);
66
67        o.execute(data);
68    }
69
70    template <class, class Target>
71    static void execute_body(ExitEvent, Target& target, ...) {
72        MIL_MODULE_SUPER_CHILD_TYPE(Target)& o =
73            MIL_MODULE_GET_SUPER_CHILD(target);
74
75        o.destroy();
76    }
77
78    template <class EventData, class Target>
79    static void execute(EventData& data, Target& target) {
80        execute_body<EventData, Target>(data, target, SFINAE_DUMMY_VALUE);
81    }
82};
83
84struct AutoJoiner {
85    void* obj;
86    void (*post_exit)(void*, void*);
87    void (*join)(void*);
88    char event_memory[sizeof(void*) * 10];
89};
90
91extern int auto_joiner_index;
92extern AutoJoiner auto_joiners[MIL_MAX_THREADS];
93
94template <class T>
95void post_exit_template(void* obj, void* event_memory) {
96    MIL_MODULE_SUPER_CHILD_TYPE(T)& o =
97        MIL_MODULE_GET_SUPER_CHILD(*reinterpret_cast<T*>(obj));
98
99    o.requestExit(event_memory);
100}
101
102template <class T>
103void join_template(void* obj) {
104    MIL_MODULE_SUPER_CHILD_TYPE(T)& o =
105        MIL_MODULE_GET_SUPER_CHILD(*reinterpret_cast<T*>(obj));
106
107    o.join();
108}
109
110template <class T>
111void set_auto_join(T* t) {
112    auto_joiners[auto_joiner_index].obj = reinterpret_cast<void*>(t);
113    auto_joiners[auto_joiner_index].post_exit = post_exit_template<T>;
114    auto_joiners[auto_joiner_index].join = join_template<T>;
115    auto_joiner_index++;
116}
117
118static inline void do_auto_join() {
119    for (int i = 0; i < auto_joiner_index; i++) {
120        auto_joiners[i].post_exit(auto_joiners[i].obj, auto_joiners[i].event_memory);
121    }
122    for (int i = 0; i < auto_joiner_index; i++) {
123        auto_joiners[i].join(auto_joiners[i].obj);
124    }
125    auto_joiner_index = 0;
126}
127
128template <class Child, template <class> class ThreadType>
129class ModuleCommon : public Thread<ModuleCommon<Child, ThreadType>, ThreadType> {
130public:
131    Tls tls;
132    MIL_CRTP_CLASS_MEMBERS;
133
134    ModuleCommon() : tls(this->thread_id) {
135        set_auto_join(&MIL_MODULE_GET_SUPER_CHILD(*this));
136    }
137
138    ~ModuleCommon() {
139    }
140};
141
142class ExitNotifier : public ModuleCommon<ExitNotifier, MIL_DEFAULT_THREAD> {
143public:
144    //void requestExit(void* event_memory)
145    void requestExit(void*) {
146    }
147
148    template <typename T, typename Sender>
149    //void post(const T& event, Sender& sender, void* memory, intptr_t owner_id)
150    void post(const T&, Sender&, void*, intptr_t) {
151    }
152
153    template <typename T, typename Sender>
154    void post(const T& event, Sender& sender) {
155    }
156};
157extern ExitNotifier exitNotifier;
158
159}
160
Note: See TracBrowser for help on using the browser.