@@ -76,8 +76,56 @@ game_value Connection::cmd_createConnectionArray(uintptr_t, game_value_parameter
7676 return newCon;
7777}
7878
79- game_value Connection::cmd_query (uintptr_t , game_value_parameter con, game_value_parameter qu) {
79+
80+ class callstack_item_WaitForQueryResult : public vm_context ::callstack_item {
81+
82+ public:
83+
84+ callstack_item_WaitForQueryResult (ref<GameDataDBAsyncResult> inp) : res(inp) {}
85+
86+ const char * getName () const override { return " stuff" ; };
87+ int varCount () const override { return 0 ; };
88+ int getVariables (const IDebugVariable** storage, int count) const override { return 0 ; };
89+ types::__internal::I_debug_value::RefType EvaluateExpression (const char * code, unsigned rad) override { return {}; };
90+ void getSourceDocPosition (char * file, int fileSize, int & line) override {};
91+ IDebugScope* getParent () override { __debugbreak (); return nullptr ; };
92+ r_string get_type () const override { return " stuff" sv; }
93+
94+
95+
96+
97+ game_instruction* next (int & d1, const game_state* s) override {
98+ if (res->data ->res .wait_for (std::chrono::nanoseconds (0 )) == std::future_status::ready) {
99+
100+ // push result onto stack.
101+ auto gd_res = new GameDataDBResult ();
102+ gd_res->res = res->data ->res .get ();
103+ s->current_context ->scriptStack [_stackEndAtStart] = game_value (gd_res);
104+ d1 = 2 ; // done
105+ } else {
106+ d1 = 3 ; // wait
107+ }
108+
109+ return nullptr ;
110+ };
111+ bool someEH (void * state) override { return false ; };
112+ bool someEH2 (void * state) override { return false ; };
113+ void on_before_exec () override {
114+
115+ };
116+
117+ ref<GameDataDBAsyncResult> res;
118+
119+
120+ };
121+
122+ game_value Connection::cmd_query (uintptr_t g , game_value_parameter con, game_value_parameter qu) {
123+
124+ auto gs = reinterpret_cast <game_state*>(g);
80125
126+
127+
128+
81129 auto session = con.get_as <GameDataDBConnection>()->session ;
82130 auto query = qu.get_as <GameDataDBQuery>();
83131
@@ -93,12 +141,35 @@ game_value Connection::cmd_query(uintptr_t, game_value_parameter con, game_value
93141 default : ;
94142 }
95143 }
96- auto res = statement->query ();
97-
98- auto gd_res = new GameDataDBResult ();
99- gd_res->res = res;
100144
101- return gd_res;
145+
146+ if (!gs->current_context ->scheduled ) {
147+ auto res = statement->query ();
148+
149+ auto gd_res = new GameDataDBResult ();
150+ gd_res->res = res;
151+
152+ return gd_res;
153+ }
154+ // Set up callstack item to suspend while waiting
155+
156+ auto & cs = reinterpret_cast <game_state*>(g)->current_context ->callstack ;
157+
158+ auto gd_res = new GameDataDBAsyncResult ();
159+ gd_res->data = std::make_shared<GameDataDBAsyncResult::dataT>();
160+ gd_res->data ->res =
161+ std::async ([statement]() -> mariadb::result_set_ref {
162+ return statement->query ();
163+ });
164+
165+
166+ auto newItem = new callstack_item_WaitForQueryResult (gd_res);
167+ newItem->_parent = cs.back ();
168+ newItem->_stackEndAtStart = gs->current_context ->scriptStack .size ()-2 ;
169+ newItem->_stackEnd = newItem->_stackEndAtStart +1 ;
170+ newItem->_varSpace .parent = &cs.back ()->_varSpace ;
171+ cs.emplace_back (newItem);
172+ return 123 ;
102173}
103174
104175game_value Connection::cmd_queryAsync (uintptr_t , game_value_parameter con, game_value_parameter qu) {
@@ -109,18 +180,17 @@ game_value Connection::cmd_queryAsync(uintptr_t, game_value_parameter con, game_
109180 auto gd_res = new GameDataDBAsyncResult ();
110181 gd_res->data = std::make_shared<GameDataDBAsyncResult::dataT>();
111182 gd_res->data ->res =
112- std::async ([session, stmt = query->queryString , boundV = query->boundValues ]() -> mariadb::result_set_ref
183+ std::async (std::launch::async, [session, stmt = query->queryString , boundV = query->boundValues ]() -> mariadb::result_set_ref
113184 {
114185 auto statement = session->create_statement (stmt);
115186
116187 uint32_t idx = 0 ;
117188 for (auto & it : boundV) {
118189
119190 switch (it.type_enum ()) {
120- case game_data_type::SCALAR: statement->set_float (idx++, static_cast <float >(it)); break ;
121- case game_data_type::BOOL: statement->set_boolean (idx++, static_cast <bool >(it)); break ;
122- case game_data_type::STRING: statement->set_string (idx++, static_cast <r_string>(it)); break ;
123- default :;
191+ case game_data_type::SCALAR: statement->set_float (idx++, static_cast <float >(it)); break ;
192+ case game_data_type::BOOL: statement->set_boolean (idx++, static_cast <bool >(it)); break ;
193+ case game_data_type::STRING: statement->set_string (idx++, static_cast <r_string>(it)); break ;
124194 }
125195 }
126196 return statement->query ();
0 commit comments