/*! * \brief Create temporary directory in designated directory. * \param basePath [out] Path of temporary directory.<br> * Process is failure, if return is null.<br> * Need call "free", if return is not null. * \param wishesName [in] Name of one's wishes directory name. * \return Value is zero, if process is succeed.<br /> * Value is error number a.k.a. "errno", if process is failure. */ int createTempDir(char **basePath, char const *wishesName) { char *uniqName = NULL; /* Sanity check. */ if (unlikely(basePath == NULL || wishesName == NULL)) { logger->printWarnMsg("Illegal directory path."); return -1; } int raisedErrNum = -1; /* Get mutex. */ ENTER_PTHREAD_SECTION(&directoryMutex) { /* Create unique directory path. */ uniqName = createUniquePath((char *)wishesName, true); if (unlikely(uniqName == NULL)) { raisedErrNum = errno; } else { /* If failed to create temporary directory. */ if (unlikely(mkdir(uniqName, S_IRUSR | S_IWUSR | S_IXUSR) != 0)) { raisedErrNum = errno; } else { raisedErrNum = 0; } } } /* Release mutex. */ EXIT_PTHREAD_SECTION(&directoryMutex) /* If failed to create temporary directory. */ if (unlikely(raisedErrNum != 0)) { free(uniqName); uniqName = NULL; } /* Copy directory path. */ (*basePath) = uniqName; return raisedErrNum; }
/*! * \brief Copy data as avoid overwriting. * \param sourceFile [in] Path of source file. * \param destPath [in] Path of directory put duplicated file. * \param destName [in] Name of duplicated file.<br> * Don't rename, if value is null. * \return Value is zero, if process is succeed.<br /> * Value is error number a.k.a. "errno", if process is failure. */ int copyFile(char const *sourceFile, char const *destPath, char const *destName) { char rpath[PATH_MAX]; if (unlikely(!isCopiablePath(sourceFile, rpath))) { return EINVAL; } int result = 0; /* Make file name. */ char *newFile = destName == NULL ? createFilename(destPath, (char *)sourceFile) : createFilename(destPath, (char *)destName); /* Failure make filename. */ if (unlikely(newFile == NULL)) { logger->printWarnMsg("Couldn't allocate copy source file path."); /* * Because exist below two pattern when "createFilename" return NULL. * 1, Illegal argument. "errno" don't change. * 2, No usable memory. "errno" maybe "ENOMEM". */ return (errno != 0) ? errno : EINVAL; } /* Get uniq file name. */ char *destFile = createUniquePath(newFile, false); if (unlikely(destFile == NULL)) { logger->printWarnMsg("Couldn't allocate unique destination file name."); free(newFile); return ENOMEM; } /* Open copy source file. */ int sourceFd = open(sourceFile, O_RDONLY); if (unlikely(sourceFd < 0)) { result = errno; logger->printWarnMsgWithErrno("Couldn't open copy source file."); free(newFile); free(destFile); return result; } /* Get source file size */ struct stat st; if (unlikely(fstat(sourceFd, &st) != 0)) { result = errno; logger->printWarnMsgWithErrno("Couldn't open copy destination file."); free(newFile); free(destFile); close(sourceFd); return result; } /* Open destination file. */ int destFd = open(destFile, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR); if (unlikely(destFd < 0)) { result = errno; logger->printWarnMsgWithErrno("Couldn't open copy destination file."); free(newFile); free(destFile); close(sourceFd); return result; } /* Copy data */ if (st.st_size > 0) { if (unlikely(sendfile64(destFd, sourceFd, NULL, st.st_size) == -1)) { result = errno; logger->printWarnMsgWithErrno("Couldn't copy file."); } } else { /* This route is for files in procfs */ char buf[1024]; ssize_t read_size; while ((read_size = read(sourceFd, buf, 1024)) > 0) { if (write(destFd, buf, (size_t)read_size) == -1) { read_size = -1; break; } } if (read_size == -1) { result = errno; logger->printWarnMsgWithErrno("Couldn't copy file."); } } /* Clean up */ close(sourceFd); if (unlikely((close(destFd) != 0) && (result == 0))) { result = errno; logger->printWarnMsgWithErrno("Couldn't write copy file data."); } free(newFile); free(destFile); return result; }
RootController(ci::JsonTree& params, ci::TimelineRef timeline, Event<std::vector<Touch> >& touch_event) noexcept : params_(params), timeline_(timeline), ui_camera_(createCamera(params["ui_view.camera"])), fov_(ui_camera_.getFov()), near_z_(ui_camera_.getNearClip()), far_z_(ui_camera_.getFarClip()), autolayout_(ui_camera_), touch_event_(touch_event), view_creator_(params, timeline, ui_camera_, autolayout_, event_, touch_event), sound_(params["sounds"]), background_(Json::getColor<float>(params["app.background"])), records_(params["version"].getValue<float>()) { DOUT << "RootController()" << std::endl; event_.connect("begin-progress", [this](const Connection&, EventParam& param) noexcept { addController<ProgressController>(params_, timeline_, event_, view_creator_.create("ui_progress.json")); }); event_.connect("begin-gameover", [this](const Connection&, EventParam& param) noexcept { addController<GameoverController>(params_, timeline_, event_, param, view_creator_.create("ui_gameover.json")); }); event_.connect("begin-stageclear", [this](const Connection&, EventParam& param) noexcept { addController<StageclearController>(params_, timeline_, event_, param, view_creator_.create("ui_stageclear.json")); }); event_.connect("begin-pause", [this](const Connection&, EventParam& param) noexcept { addController<PauseController>(params_, timeline_, event_, view_creator_.create("ui_pause.json")); }); event_.connect("begin-records", [this](const Connection&, EventParam& param) noexcept { EventParam records = { { "total_play", records_.getTotalPlayNum() }, { "total_time", records_.getTotalPlayTime() }, { "high_score", records_.getHighScore() }, { "total_item", records_.getTotalItemNum() }, { "stage_ranks", records_.stageRanks() }, }; addController<RecordsController>(params_, timeline_, event_, records, view_creator_.create("ui_records.json")); }); event_.connect("begin-credits", [this](const Connection&, EventParam& param) noexcept { addController<CreditsController>(params_, timeline_, event_, view_creator_.create("ui_credits.json")); }); event_.connect("begin-title", [this](const Connection&, EventParam& param) noexcept { startTitle(param); }); event_.connect("begin-settings", [this](const Connection&, EventParam& param) noexcept { addController<SettingsController>(params_, timeline_, event_, records_, view_creator_.create("ui_settings.json")); }); event_.connect("begin-regulat-stageclear", [this](const Connection&, EventParam& param) noexcept { addController<AllStageClearController>(params_["regular_stageclear"], timeline_, event_, param, view_creator_.create("ui_regularstageclear.json")); }); event_.connect("begin-all-stageclear", [this](const Connection&, EventParam& param) noexcept { addController<AllStageClearController>(params_["all_stageclear"], timeline_, event_, param, view_creator_.create("ui_allstageclear.json")); }); // GameOver時に色々チェック event_.connect("check-after-gameover", [this](const Connection&, EventParam& param) noexcept { DOUT << "check-after-gameover" << std::endl; Rating::popup([this]() { AppSupport::pauseDraw(true); }, [this]() { AppSupport::pauseDraw(false); }); Achievment::atGameOver(records_); }); // サウンド再生 event_.connect("sound-play", [this](const Connection&, EventParam& param) noexcept { auto& name = boost::any_cast<const std::string&>(param.at("sound")); player_.play(name); // DOUT << "sound:" << name << std::endl; }); event_.connect("se-silent", [this](const Connection&, EventParam& param) noexcept { sound_.setBufferSilent(boost::any_cast<bool>(param["silent"])); }); event_.connect("bgm-silent", [this](const Connection&, EventParam& param) noexcept { sound_.setFileSilent(boost::any_cast<bool>(param["silent"])); }); #ifdef DEBUG event_.connect("force-regular-completed", [this](const Connection&, EventParam& param) noexcept { records_.forceRegularStageComplated(); }); event_.connect("cancel-regular-completed", [this](const Connection&, EventParam& param) noexcept { records_.cancelRegularStageComplated(); }); event_.connect("clear-records", [this](const Connection&, EventParam& param) noexcept { records_ = Records(params_["version"].getValue<float>()); }); event_.connect("do-snapshot", [this](const Connection&, EventParam& param) noexcept { auto surface = ci::app::copyWindowSurface(); auto full_path = getDocumentPath() / std::string("snapshot" + createUniquePath() + ".png"); ci::writeImage(full_path, surface); }); event_.connect("reset-records", [this](const Connection&, EventParam& param) noexcept { records_ = Records(params_["version"].getValue<float>()); }); event_.connect("reset-achievement", [this](const Connection&, EventParam& param) noexcept { DOUT << "reset-achievement" << std::endl; GameCenter::resetAchievement(); }); #endif records_.load(params["game.records"].getValue<std::string>()); sound_.setBufferSilent(!records_.isSeOn()); sound_.setFileSilent(!records_.isBgmOn()); addController<FieldController>(params, touch_event_, event_, records_); addController<IntroController>(params_, timeline_, event_, records_.getTotalPlayNum(), view_creator_.create("ui_intro.json")); // 自動PAUSE // getSignalDidEnterBackground(Backgroundになった直後) // getSignalWillResignActive(アクティブでなくなる直前) resign_active_ = ci::app::App::get()->getSignalWillResignActive().connect([this]() noexcept { DOUT << "SignalWillResignActive" << std::endl; EventParam params = { { "force", true } }; event_.signal("pause-agree", params); GameCenter::writeCachedAchievement(); }); }