CRAW now runs on Windows 7 too - the problem was that Windows 7 has moved some functi...
[craw.git] / craw / python_callback.cpp
blob13fac773d1968ce166fde02c3e60c8feed4064eb
1 #include <boost/thread/mutex.hpp>
2 #include "d2_functions.hpp"
3 #include "python.hpp"
4 #include "utility.hpp"
6 namespace python
8 namespace
10 boost::mutex python_mutex;
13 struct global_interpreter_lock
15 PyGILState_STATE gil_state;
17 global_interpreter_lock()
19 gil_state = PyGILState_Ensure();
22 ~global_interpreter_lock()
24 PyGILState_Release(gil_state);
28 void perform_automap_callback(unit & current_unit, int x, int y, uchar colour)
30 if(!automap_handler)
31 return;
33 boost::mutex::scoped_lock lock(python_mutex);
34 //global_interpreter_lock lock;
36 python_monster_data * monster_data_pointer = PyObject_New(python_monster_data, &monster_data_type);
37 python_monster_data & current_monster_data = *monster_data_pointer;
38 if(!current_monster_data.initialise(current_unit))
39 exit_process();
41 current_monster_data.x = x;
42 current_monster_data.y = y;
43 current_monster_data.colour = colour;
45 PyObject * return_value = PyObject_CallFunction(automap_handler, "O", monster_data_pointer);
47 Py_XDECREF(current_monster_data.treasure_class);
48 Py_XDECREF(current_monster_data.special_abilities);
49 Py_DECREF(monster_data_pointer);
51 if(!return_value)
53 PyErr_Print();
54 return;
57 Py_DECREF(return_value);
60 bool perform_packet_callback(std::string const & packet)
62 if(!packet_handler)
63 return true;
65 boost::mutex::scoped_lock lock(python_mutex);
66 //global_interpreter_lock lock;
68 PyObject * packet_string = create_string(packet);
70 PyObject * return_value = PyObject_CallFunction(packet_handler, "O", packet_string);
71 if(!return_value)
73 PyErr_Print();
74 return true;
77 bool output = (return_value == Py_True);
79 Py_DECREF(packet_string);
80 Py_DECREF(return_value);
82 return output;
85 bool perform_command_callback(std::string const & line)
87 if(!command_handler)
88 return false;
90 boost::mutex::scoped_lock lock(python_mutex);
92 PyObject * argument = create_string(line);
94 PyObject * return_value = PyObject_CallFunction(command_handler, "O", argument);
95 if(!return_value)
97 PyErr_Print();
98 return false;
101 bool output = (return_value == Py_True);
103 Py_DECREF(argument);
104 Py_DECREF(return_value);
106 return output;
109 bool perform_keyboard_callback(unsigned virtual_key)
111 if(!keyboard_handler)
112 return false;
114 boost::mutex::scoped_lock lock(python_mutex);
116 PyObject * argument = PyLong_FromUnsignedLong(virtual_key);
117 PyObject * return_value = PyObject_CallFunction(keyboard_handler, "O", argument);
118 if(!return_value)
120 PyErr_Print();
121 return false;
124 Py_XDECREF(argument);
125 Py_DECREF(return_value);
127 return true;
130 bool perform_bncs_callback(std::string const & packet)
132 if(!bncs_packet_handler)
133 return false;
135 boost::mutex::scoped_lock lock(python_mutex);
137 PyObject * argument = PyString_FromStringAndSize(packet.c_str(), packet.size());
138 PyObject * return_value = PyObject_CallFunction(bncs_packet_handler, "O", argument);
139 if(!return_value)
141 PyErr_Print();
142 return false;
145 Py_XDECREF(argument);
146 Py_DECREF(return_value);
148 return true;
151 void perform_item_callback(unit & current_item)
153 if(!item_handler)
154 return;
156 boost::mutex::scoped_lock lock(python_mutex);
158 item_text * item_text_pointer = d2_get_item_text(current_item.table_index);
159 if(item_text_pointer == 0)
161 error("Item text pointer is 0 for item " + ail::hex_string_32(reinterpret_cast<unsigned>(&current_item)));
162 exit_process();
163 return;
166 python_item_data * item_data_pointer = PyObject_New(python_item_data, &item_data_type);
167 python_item_data & current_python_item_data = *item_data_pointer;
169 current_python_item_data.id = current_item.id;
171 wchar_t * unicode_name = get_unit_name(&current_item);
172 std::string name = wchar_to_string(unicode_name);
173 current_python_item_data.type = create_string(name);
175 std::string code = item_text_pointer->get_code();
176 current_python_item_data.code = create_string(code);
178 item_data & current_item_data = *current_item.item_data_pointer;
180 current_python_item_data.level = current_item_data.item_level;
181 current_python_item_data.quality = current_item_data.quality;
183 current_python_item_data.sockets = d2_get_unit_stat(&current_item, 0xc2, 0);
185 current_python_item_data.ethereal = (current_item_data.flags & 0x00400000 ? Py_True : Py_False);
187 Py_INCREF(current_python_item_data.ethereal);
189 PyObject * return_value = PyObject_CallFunction(item_handler, "O", item_data_pointer);
190 if(!return_value)
192 PyErr_Print();
193 return;
196 Py_DECREF(current_python_item_data.ethereal);
197 Py_XDECREF(current_python_item_data.type);
198 Py_XDECREF(current_python_item_data.code);
199 Py_XDECREF(item_data_pointer);
200 Py_DECREF(return_value);