void recurse_object(const mxArray* in, json& obj) { // Go over all types if (mxIsCell(in)) { int N = mxGetNumberOfElements(in); for (int a = 0; a < N; ++a) { obj.emplace_back(); recurse_object(mxGetCell(in, a), obj.back()); } } else if (mxIsStruct(in)) { int M = mxGetNumberOfFields(in); std::vector<const char*> fnames(M); for (int b = 0; b < M; ++b) fnames[b] = mxGetFieldNameByNumber(in, b); int N = mxGetNumberOfElements(in); for (int a = 0; a < N; ++a) { json obj_; for (int b = 0; b < M; ++b) recurse_object(mxGetFieldByNumber(in, a, b), obj_[fnames[b]]); if (N == 1) obj = std::move(obj_); else obj.push_back(std::move(obj_)); } } else if (mxIsChar(in)) { obj = json::parse(mxArrayToString(in)); } else if (mxIsLogical(in)) { int N = mxGetNumberOfElements(in); const mxLogical* data = (const mxLogical*)mxGetData(in); if (N == 1) { obj = data[0] != 0; } else { for (int a = 0; a < N; ++a) obj.push_back(data[a] != 0); } } else if (mxIsNumeric(in)) { int N = mxGetNumberOfElements(in); const void* data = (const void*)mxGetData(in); switch (mxGetClassID(in)) { case mxDOUBLE_CLASS: if (N == 1) { obj = ((const double*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const double*)data)[a]); } break; case mxSINGLE_CLASS: if (N == 1) { obj = ((const float*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const float*)data)[a]); } break; case mxUINT8_CLASS: if (N == 1) { obj = ((const uint8_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const uint8_t*)data)[a]); } break; case mxINT8_CLASS: if (N == 1) { obj = ((const int8_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const int8_t*)data)[a]); } break; case mxUINT16_CLASS: if (N == 1) { obj = ((const uint16_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const uint16_t*)data)[a]); } break; case mxINT16_CLASS: if (N == 1) { obj = ((const int16_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const int16_t*)data)[a]); } break; case mxUINT32_CLASS: if (N == 1) { obj = ((const uint32_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const uint32_t*)data)[a]); } break; case mxINT32_CLASS: if (N == 1) { obj = ((const int32_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const int32_t*)data)[a]); } break; case mxUINT64_CLASS: if (N == 1) { obj = ((const uint64_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const uint64_t*)data)[a]); } break; case mxINT64_CLASS: if (N == 1) { obj = ((const int64_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const int64_t*)data)[a]); } break; default: mexErrMsgTxt("Unsupported type."); break; } } else { mexErrMsgTxt("Unrecognized type."); } }
/* * rmtree * * Delete a directory tree recursively. * Assumes path points to a valid directory. * Deletes everything under path. * If rmtopdir is true deletes the directory too. */ bool rmtree(char *path, bool rmtopdir) { char pathbuf[MAXPGPATH]; char *filepath; char **filenames; char **filename; struct stat statbuf; /* * we copy all the names out of the directory before we start modifying * it. */ filenames = fnames(path); if (filenames == NULL) return false; /* now we have the names we can start removing things */ filepath = pathbuf; for (filename = filenames; *filename; filename++) { snprintf(filepath, MAXPGPATH, "%s/%s", path, *filename); if (lstat(filepath, &statbuf) != 0) goto report_and_fail; if (S_ISDIR(statbuf.st_mode)) { /* call ourselves recursively for a directory */ if (!rmtree(filepath, true)) { /* we already reported the error */ fnames_cleanup(filenames); return false; } } else { if (unlink(filepath) != 0) goto report_and_fail; } } if (rmtopdir) { filepath = path; if (rmdir(filepath) != 0) goto report_and_fail; } fnames_cleanup(filenames); return true; report_and_fail: #ifndef FRONTEND elog(WARNING, "could not remove file or directory \"%s\": %m", filepath); #else fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), filepath, strerror(errno)); #endif fnames_cleanup(filenames); return false; }
int main(int argc, char *argv[]) { int ret = 0; std::vector<const char*> fnames(4); std::vector<std::vector<BaseGameObject*>> ordered_render_objects; struct engine_context context; struct engine_config cfg; context.cfg = &cfg; cfg.screen_position_x = 50; cfg.screen_position_y = 50; cfg.window_width = 800; cfg.window_height = 450; cfg.subsystem_flags = SDL_INIT_VIDEO; cfg.window_flags = SDL_WINDOW_SHOWN; cfg.renderer_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC; active_context = &context; // initialize subsystems ret = engine_init(&context); if (ret) { ret = 1; goto main_exit; } // SDL 2.0 now uses textures to draw things but SDL_LoadBMP returns a surface // this lets us choose when to upload or remove textures from the GPU if (deserialize_objects_from_file(game_setup_file, &scene_root)) { goto main_exit; } for (size_t i = 0; i < scene_root.size(); i++) { objects.insert(objects.begin(), scene_root[i]); scene_root[i]->get_all_children(&objects); } ordered_render_objects.resize(4); ordered_render_objects[0].resize(1); ordered_render_objects[0][0] = objects[0]; ordered_render_objects[1].resize(1); ordered_render_objects[1][0] = objects[1]; ordered_render_objects[2].resize(1); ordered_render_objects[2][0] = objects[2]; ordered_render_objects[3].resize(1); ordered_render_objects[3][0] = objects[3]; // render loop bool run = true; engine_time_init(); Vector2 *m = new Vector2(24.0f, 24.0f); while (run) { SDL_Event event; engine_time_update(); if (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT || event.type == SDL_KEYDOWN || event.type == SDL_MOUSEBUTTONDOWN) { std::cout << "bye bye" << std::endl; run = false; } } // clear the renderer SDL_RenderClear(active_context->renderer); for (size_t sorting_layer = 0; sorting_layer < ordered_render_objects.size(); sorting_layer++) { for (size_t sorting_order = 0; sorting_order < ordered_render_objects[sorting_layer].size(); sorting_order++) { ordered_render_objects[sorting_layer][sorting_order]->draw(); } } scene_root[0]->move_by(&(*m * Time.delta_time)); if (scene_root[0]->get_position().y > cfg.window_height / 2) { scene_root[0]->move_to(&Vector2(0, 0)); } // present the content rendered to the renderer SDL_RenderPresent(active_context->renderer); } delete m; main_exit: serialize_objects_to_file("out.json", &scene_root); //Clean up our objects and quit for (std::vector<BaseGameObject*>::iterator it = objects.begin(); it != objects.end(); it++) { delete (*it); } SDL_DestroyRenderer(context.renderer); SDL_DestroyWindow(context.window); SDL_Quit(); return (ret); }