コード例 #1
0
ファイル: video_meta_cache.cpp プロジェクト: s133p/ds_cinder
void VideoMetaCache::setValues(Entry& entry) {
	if(entry.mType == ERROR_TYPE) {
		DS_LOG_WARNING("Attempted to cache an invalid media (path=" << entry.mPath << ")");
		return;
	}
	if(entry.mDuration < 0.0f) {
		DS_LOG_WARNING("Attempted to cache media with no duration (path=" << entry.mPath << ")");
		return;
	}
	if(entry.mType == VIDEO_TYPE && (entry.mWidth < 1 || entry.mHeight < 1)) {
		DS_LOG_WARNING("Attempted to cache video with no size (path=" << entry.mPath << ", width=" << entry.mWidth << ", height=" << entry.mHeight << ")");
		return;
	}
	try {
		const std::string				db = get_db_file(mName);
		std::stringstream				buf;
		buf << "SELECT id FROM video_meta WHERE path='" << entry.mPath << "'";
		ds::query::Result						ans;
		if (ds::query::Client::query(db, buf.str(), ans) && !ans.rowsAreEmpty()) {
			buf.str("");
			buf << "UPDATE video_meta SET type='" << db_type_from_type(entry.mType) 
				<< "', width=" << entry.mWidth 
				<< ", height=" << entry.mHeight 
				<< ", duration=" << entry.mDuration
				<< ", colorspace='" << entry.mDuration
				<< "', videocodec='" << entry.mDuration
				<< "', audiocodec='" << entry.mDuration
				<< "' WHERE path='" << entry.mPath << "'";
			ds::query::Client::queryWrite(db, buf.str(), ans);
			load();
			return;
		}
		buf.str("");
		buf << "INSERT INTO video_meta (type, path, width, height, duration, colorspace, videocodec, audiocodec) values ('" << 
			db_type_from_type(entry.mType) << "', '" 
			<< entry.mPath << "', " 
			<< entry.mWidth << ", " 
			<< entry.mHeight << ", " 
			<< entry.mDuration << ", '" 
			<< entry.mColorSpace << "', '" 
			<< entry.mVideoCodec << "', '" 
			<< entry.mAudioCodec << "')";
		ds::query::Client::queryWrite(db, buf.str(), ans);
		mEntries.push_back(entry);
	} catch (std::exception const&) {
	}

	//load();
}
コード例 #2
0
void EngineSettings::printStartupInfo(){
	if(mLoadedAnySettings){
		DS_LOG_INFO(std::endl << mStartupInfo.str());
	} else {
		DS_LOG_WARNING("No settings files loaded. Using default values.");
	}
}
コード例 #3
0
void ThreatQuery::query() {
	const ds::Resource::Id			cms(ds::Resource::Id::CMS_TYPE, 0);
	std::stringstream				buf;
	ds::query::Result				r;
	ds::query::Result				threatR;
	buf << "SELECT latest_threats.id, latest_threats.name FROM latest_threats ORDER BY id DESC LIMIT 10";
	if (!ds::query::Client::query(cms.getDatabasePath(), buf.str(), r, ds::query::Client::INCLUDE_COLUMN_NAMES_F)) {
		DS_LOG_WARNING("TreatQuery error querying treats");
	}
	if (r.rowsAreEmpty()) return;

	// Add the media
	ds::query::Result::RowIterator	it(r);
	while (it.hasValue()) {
		LatestThreatModel m;
		m.mThreatId =it.getInt(0);
		m.mName = it.getWString(1);

		buf.str("");
		buf << "SELECT country, startDate, infections FROM threat_data WHERE threatID = " << m.mThreatId;
		if(ds::query::Client::query(cms.getDatabasePath(), buf.str(), threatR, ds::query::Client::INCLUDE_COLUMN_NAMES_F) && !threatR.rowsAreEmpty()){
			ds::query::Result::RowIterator threatIt(threatR);
			while(threatIt.hasValue()){
				ThreatDataModel tdm;
				tdm.mCountry = threatIt.getWString(0);
				tdm.mDate = threatIt.getWString(1);
				tdm.mNumThreats = threatIt.getInt(2);
				m.mThreatData.push_back(tdm);
				++threatIt;
			}
		}
		mLatestThreats.push_back(m);
		++it;
	}
}
コード例 #4
0
void PngSequenceSprite::setImages(const std::vector<std::string>& imageFiles){
	size_t i=0;
	for(auto it = imageFiles.begin(); it < imageFiles.end(); ++it){
		bool created_new_frames = false;
		while ( mFrames.size() < i+1 ) {
			ds::ui::Image* img = new ds::ui::Image( mEngine, (*it), ds::ui::Image::IMG_CACHE_F | ds::ui::Image::IMG_PRELOAD_F );
			addChild( *img );
			img->hide();
			mFrames.push_back( img );
			created_new_frames = true;
		}

		if (!created_new_frames)
			mFrames[i]->setImageFile( *it, ds::ui::Image::IMG_CACHE_F | ds::ui::Image::IMG_PRELOAD_F );

		i++;
	}

	mNumFrames = imageFiles.size();

	// Hide all the old frames if there were previously more frames than there are now
	for ( i=mNumFrames; i<mFrames.size(); i++ )
		mFrames[i]->hide();

	if( mNumFrames == 0 ){
		DS_LOG_WARNING("Png Sequence didn't load any frames. Whoops.");
		mPlaying = false;
		return;
	}
}
コード例 #5
0
const ds::cfg::Text& EngineCfg::getText(const std::string& name) const {
	if (name.empty()) {
		DS_LOG_WARNING("EngineCfg::getText() on empty name");
		return mEmptyTextCfg;
	}
	if (mTextCfg.empty()) {
		DS_LOG_WARNING("EngineCfg::getText() on empty mTextCfg (key=" << name << ")");
		return mEmptyTextCfg;
	}
	auto it = mTextCfg.find(name);
	if (it == mTextCfg.end()) {
		DS_LOG_WARNING("EngineCfg::getText() cfg does not exist: " << name);
		return mEmptyTextCfg;
	}
	return it->second;
}
コード例 #6
0
ファイル: video_meta_cache.cpp プロジェクト: s133p/ds_cinder
bool VideoMetaCache::getVideoInfo(Entry& entry) {
	MediaInfoDLL::MediaInfo		media_info;
	if (!media_info.IsReady()) {
		// Indicates the DLL couldn't be loaded
		DS_LOG_ERROR("VideoMetaCache::getVideoInfo() MediaInfo not loaded, does dll/MediaInfo.dll exist in the app folder?");
		throw std::runtime_error("VideoMetaCache::getVideoInfo() MediaInfo not loaded, does dll/MediaInfo.dll exist in the app folder?");
		return false;
	}
	media_info.Open(ds::wstr_from_utf8(entry.mPath));
	
	size_t numAudio = media_info.Count_Get(MediaInfoDLL::Stream_Audio);
	size_t numVideo = media_info.Count_Get(MediaInfoDLL::Stream_Video);

	if(numAudio < 1 && numVideo < 1){
		DS_LOG_WARNING("Couldn't find any audio or video streams in " << entry.mPath);
		entry.mType = ERROR_TYPE;
		return false;
	}

	// If there's an audio channel, get it's codec
	if(numAudio > 0){
		entry.mAudioCodec = ds::utf8_from_wstr(media_info.Get(MediaInfoDLL::Stream_Audio, 0, L"Codec", MediaInfoDLL::Info_Text));
	}


	// No video streams, but has at least one audio stream is a AUDIO_TYPE
	if(numAudio > 0 && numVideo < 1){
		entry.mType = AUDIO_TYPE;
		entry.mWidth = 0;
		entry.mHeight = 0;
		if(!ds::wstring_to_value(media_info.Get(MediaInfoDLL::Stream_Audio, 0, L"Duration", MediaInfoDLL::Info_Text), entry.mDuration)) return false;

	// Any number of audio streams and at least one video streams is VIDEO_TYPE
	} else if(numVideo > 0){
		entry.mType = VIDEO_TYPE;
		if(!ds::wstring_to_value(media_info.Get(MediaInfoDLL::Stream_Video, 0, L"Width", MediaInfoDLL::Info_Text), entry.mWidth)) return false;
		if(!ds::wstring_to_value(media_info.Get(MediaInfoDLL::Stream_Video, 0, L"Height", MediaInfoDLL::Info_Text), entry.mHeight)) return false;

		// We don't check errors on these, cause they're not required by gstreamer to play a video, they're just nice-to-have
		entry.mVideoCodec = ds::utf8_from_wstr(media_info.Get(MediaInfoDLL::Stream_Video, 0, L"Codec", MediaInfoDLL::Info_Text));
		entry.mColorSpace = ds::utf8_from_wstr(media_info.Get(MediaInfoDLL::Stream_Video, 0, L"Colorimetry", MediaInfoDLL::Info_Text));
		ds::wstring_to_value(media_info.Get(MediaInfoDLL::Stream_Video, 0, L"Duration", MediaInfoDLL::Info_Text), entry.mDuration);
	}

	entry.mDuration /= 1000.0f;

	// Disabling duration check, if MediaInfo can't find it, that's ok, GStreamer can fill it in
// 	if(entry.mDuration <= 0.0f || entry.mDuration > 360000.0f) {  // 360000.0f == 100 hours. That should be enough, right?
// 		DS_LOG_WARNING("VideoMetaCache::getVideoInfo() illegal duration (" << entry.mDuration << ") for file (" << entry.mPath << ")");
// 		return false;
// 	}
	return true;
}
コード例 #7
0
void PanoramicVideo::onChildAdded(ds::ui::Sprite& child){
	if (mVideoSprite){
		DS_LOG_WARNING("Multiple video sprites were attempted to be registered. Gonna ignore it.");
		return;
	} else if(auto video = dynamic_cast<ds::ui::Video*>(&child)){
		mVideoSprite = video;
		mVideoSprite->setTransparent(false);
		setTransparent(false);

		mVideoSprite->setFinalRenderToTexture(true);
	}
}
コード例 #8
0
void TouchManager::inputBegin(const int fingerId, const ci::Vec2f& touchPos){
	mDiscardTouchMap[fingerId] = false;

	ci::Vec3f globalPoint = ci::Vec3f(touchPos, 0.0f);

	TouchInfo touchInfo;
	touchInfo.mCurrentGlobalPoint = globalPoint;
	touchInfo.mFingerId = fingerId;
	touchInfo.mStartPoint = mTouchStartPoint[touchInfo.mFingerId] = touchInfo.mCurrentGlobalPoint;
	mTouchPreviousPoint[fingerId] = globalPoint;
	touchInfo.mDeltaPoint = ci::Vec3f::zero();

	// Catch a case where two "touch added" calls get processed for the same fingerID
	// WITHOUT a released in the middle. This would case the previous sprite to be left with an erroneous finger
	// So we fake remove it before adding the new one
	if(mFingerDispatcher[touchInfo.mFingerId]) {
		DS_LOG_WARNING("Double touch added on the same finger Id: " << touchInfo.mFingerId << ", removing previous sprite tracking.");
		touchInfo.mPickedSprite = mFingerDispatcher[touchInfo.mFingerId];
		touchInfo.mPhase = TouchInfo::Removed; // fake removed
		touchInfo.mPassedTouch = true; // passed touch flag indicates that this info shouldn't be used to trigger buttons, etc. implementation up to each sprite
		mFingerDispatcher[touchInfo.mFingerId]->processTouchInfo(touchInfo);
		mFingerDispatcher[touchInfo.mFingerId] = nullptr;

	}

	touchInfo.mPhase = TouchInfo::Added;
	touchInfo.mPassedTouch = false;

	if(mCapture) mCapture->touchBegin(touchInfo);

	Sprite *currentSprite = getHit(touchInfo.mCurrentGlobalPoint);
	touchInfo.mPickedSprite = currentSprite;
	mRotationTranslator.down(touchInfo);

	if(mSmoothEnabled){
		mTouchSmoothPoints[fingerId].clear();
		mTouchSmoothPoints[fingerId].push_back(touchInfo.mCurrentGlobalPoint);
	}

	if(currentSprite) {
		mFingerDispatcher[touchInfo.mFingerId] = currentSprite;
		currentSprite->processTouchInfo(touchInfo);
	}

	if(mEngine.getTouchInfoPipeCallback()){
		mEngine.getTouchInfoPipeCallback()(touchInfo);
	}
}
コード例 #9
0
static void read_text_defaults(std::unordered_map<std::string, ds::cfg::Text>& out) {
	ds::cfg::Settings s;

	try {
		ci::DataSourceRef ds = ci::app::App::loadResource(RES_TEXT);
		ci::Buffer&	buf = ds->getBuffer();
		if(buf.getDataSize() > 0 && buf.getDataSize() < 100000) {
			std::string	str(static_cast<const char*>(buf.getData()), buf.getDataSize());
			s.readFrom(str, true, true);
		}
	}
	catch(std::exception& e) {
		DS_LOG_WARNING("Failed to load default text settings: " << e.what());
	}

	interpret_text_settings(s, out);
}
コード例 #10
0
bool parse_stylesheet(Iter first, Iter last, Rules& s) {
	/*
	 * selector [, selector]* {
	 *	   property: value(; property: value)*(;?)
	 * }
	 */

	stylesheet_grammar<Iter> grammar;
	custom_skipper<Iter> skipper;
	bool r = qi::phrase_parse( first, last, grammar, skipper, s );

	if (r && first == last) {
		return true;
	}
	else {
		std::string context(first, last);
		DS_LOG_WARNING( "Failed to parse stylesheet here: -> " << context.substr(0, 30) << "... <-" );
	}

	return false;
}
コード例 #11
0
void NewsQuery::query() {
	const ds::Resource::Id			cms(ds::Resource::Id::CMS_TYPE, 0);
	std::stringstream				buf;
	ds::query::Result				r;
	buf << "SELECT id,year,month,day,text FROM news";
	if (!ds::query::Client::query(cms.getDatabasePath(), buf.str(), r, ds::query::Client::INCLUDE_COLUMN_NAMES_F)) {
		DS_LOG_WARNING("NewsQuery::queryType() error querying news");
	}
	if (r.rowsAreEmpty()) return;

	// Add the media
	ds::query::Result::RowIterator	it(r);
	while (it.hasValue()) {
		TickerModel m;
		m.mId =it.getInt(0);
		m.mYear = it.getInt(1);
		m.mMonth = it.getInt(2);
		m.mDay = it.getInt(3);
		m.mHeadline = it.getWString(4);
		mOutput.push_back(m);
		++it;
	}
}
コード例 #12
0
ファイル: video_meta_cache.cpp プロジェクト: s133p/ds_cinder
bool VideoMetaCache::getValues(const std::string& videoPath, Type& outType, int& outWidth, int& outHeight, double& outDuration, std::string& outColorSpace) {
	for(auto it = mEntries.begin(), end = mEntries.end(); it != end; ++it) {
		const Entry&	e(*it);
		if (e.mPath == videoPath){

// With updates to this system , I don't believe this fallback system is needed.
// Previously, a video could be assumed to be audio if it simply couldn't be found or read.
// Now, actually find audio streams, and never assume stuff like that.
// Also, if a file is type==ERROR_TYPE, it isn't recorded anywhere, so the below condition can't exist
#if 0
			// Sort of a long story, but here's the deal:
			//		1. Try to load a video that doesn't exist yet, type gets saved as audio, width=0, height=0
			//		2. Try to load that same video again, but now it exists. The cache will pull up audio, width & height = 0
			//		3. The video will then never play until the cache is cleared manually.
			//		4. So to fix that, we just re-query media info every time width or height are < 1. 
			//		5. This means audio files are queried every time. If this becomes an issue performance-wise, we can try to short-cut this.
			if(e.mWidth < 1 || e.mHeight < 1){

				Entry newEntry = Entry();
				newEntry.mPath = videoPath;

				if(getVideoInfo(newEntry) && newEntry.mType != ERROR_TYPE){
					if(width > 0 && height > 0){
						setValues(t, videoPath, width, height, duration);
						outType = t;
						outWidth = width;
						outHeight = height;
						outDuration = duration;
						return true;
					}
				}

			}

#endif 

			outType = e.mType;
			outWidth = e.mWidth;
			outHeight = e.mHeight;
			outDuration = e.mDuration;
			outColorSpace = e.mColorSpace;

			return true;
		}
	}


	// The above search for a pre-cached video info failed, so find the video info
	try {

		Entry newEntry = Entry();
		newEntry.mPath = videoPath;

		if(!getVideoInfo(newEntry) || newEntry.mType == ERROR_TYPE){
			return false;
		}

		setValues(newEntry);

		outType = newEntry.mType;
		outWidth = newEntry.mWidth;
		outHeight = newEntry.mHeight;
		outDuration = newEntry.mDuration;
		outColorSpace = newEntry.mColorSpace;
		return true;
	} catch (std::exception const& ex) {
		DS_LOG_WARNING("VideoMetaCache::getWith() error=" << ex.what());
	}
	return true;
}
コード例 #13
0
void MediaPlayer::initialize(){
	if(mInitialized) return;

	const int mediaType = mResource.getType();
	if(mediaType == ds::Resource::ERROR_TYPE || mediaType == ds::Resource::FONT_TYPE){
		// this is not a useful warning message in the very common case of setting the size of a MediaPlayer before loading the media
		// GN: This is a VERY useful message if your media isn't showing up, so we'll just check for emptiness instead of no warning
		if(!mResource.empty()){
			DS_LOG_WARNING("Whoopsies - tried to open a media player on an invalid file type. " << mResource.getAbsoluteFilePath());
		}
		return;
	}

	// do this first to avoid recursion problems
	mInitialized = true;

	float contentWidth = 1.0f;
	float contentHeight = 1.0f;
	mContentAspectRatio = 1.0f;

	bool showThumbnail = true;

	if(mediaType == ds::Resource::IMAGE_TYPE){
		int flags = 0;
		if(mMediaViewerSettings.mCacheImages){
			flags |= Image::IMG_CACHE_F;
		}
		mPrimaryImage = new ds::ui::Image(mEngine, mResource, flags);
		addChildPtr(mPrimaryImage);
		mPrimaryImage->checkStatus();
		if(mPrimaryImage->isLoaded()){
			showThumbnail = false;
		} else {
			mPrimaryImage->setOpacity(0.0f);
			mPrimaryImage->setStatusCallback([this](ds::ui::Image::Status status){
				if(status.mCode == status.STATUS_LOADED && mPrimaryImage){
					mPrimaryImage->tweenOpacity(1.0f, mAnimDuration);
					if(mStatusCallback){
						mStatusCallback(true);
					}
				}
			});
		}

		mContentAspectRatio = mPrimaryImage->getWidth() / mPrimaryImage->getHeight();
		contentWidth = mPrimaryImage->getWidth();
		contentHeight = mPrimaryImage->getHeight();

	} else if(mediaType == ds::Resource::VIDEO_TYPE){
		mVideoPlayer = new VideoPlayer(mEngine, mEmbedInterface);
		addChildPtr(mVideoPlayer);

		mVideoPlayer->setErrorCallback([this](const std::string& msg){
			if(mErrorCallback) mErrorCallback(msg);
		});

		mVideoPlayer->setGoodStatusCallback([this]{
			if(mStatusCallback) mStatusCallback(true);
		});

		mVideoPlayer->setPan(mMediaViewerSettings.mVideoPanning);
		mVideoPlayer->setAutoSynchronize(mMediaViewerSettings.mVideoAutoSync);
		mVideoPlayer->setPlayableInstances(mMediaViewerSettings.mVideoPlayableInstances);
		mVideoPlayer->setAutoPlayFirstFrame(mMediaViewerSettings.mVideoAutoPlayFirstFrame);
		mVideoPlayer->setVideoLoop(mMediaViewerSettings.mVideoLoop);

		mVideoPlayer->setMedia(mResource.getAbsoluteFilePath());


		mContentAspectRatio = mVideoPlayer->getWidth() / mVideoPlayer->getHeight();
		contentWidth = mVideoPlayer->getWidth();
		contentHeight = mVideoPlayer->getHeight();

	} else if(mediaType == ds::Resource::VIDEO_STREAM_TYPE){

		mStreamPlayer = new StreamPlayer(mEngine, mEmbedInterface);
		addChildPtr(mStreamPlayer);


		mStreamPlayer->setErrorCallback([this](const std::string& msg){
			if(mErrorCallback) mErrorCallback(msg);
		});

		mStreamPlayer->setGoodStatusCallback([this]{
			if(mStatusCallback) mStatusCallback(true);
		});

		mStreamPlayer->setResource(mResource);

		mContentAspectRatio = mStreamPlayer->getWidth() / mStreamPlayer->getHeight();
		contentWidth = mStreamPlayer->getWidth();
		contentHeight = mStreamPlayer->getHeight();

	} else if(mediaType == ds::Resource::PDF_TYPE){
		mPDFPlayer = new PDFPlayer(mEngine, mEmbedInterface);
		addChildPtr(mPDFPlayer);
		mPDFPlayer->setMedia(mResource.getAbsoluteFilePath());

		mPDFPlayer->setErrorCallback([this](const std::string& msg){
			if(mErrorCallback) mErrorCallback(msg);
		});

		mPDFPlayer->setGoodStatusCallback([this]{
			if(mStatusCallback){
				mStatusCallback(true);
			}
		});

		mContentAspectRatio = mPDFPlayer->getWidth() / mPDFPlayer->getHeight();
		contentWidth = mPDFPlayer->getWidth();
		contentHeight = mPDFPlayer->getHeight();

	} else if(mediaType == ds::Resource::WEB_TYPE){
		mWebPlayer = new WebPlayer(mEngine, mEmbedInterface);
		addChildPtr(mWebPlayer);
		mWebPlayer->setWebViewSize(mMediaViewerSettings.mWebDefaultSize);
		mWebPlayer->setKeyboardParams(mMediaViewerSettings.mWebKeyboardPanelSize, mMediaViewerSettings.mWebKeyboardKeyScale, mMediaViewerSettings.mWebAllowKeyboard);
		mWebPlayer->setAllowTouchToggle(mMediaViewerSettings.mWebAllowTouchToggle);
		mWebPlayer->setMedia(mResource.getAbsoluteFilePath());

		if(mWebPlayer->getWeb()){
			mWebPlayer->getWeb()->setDocumentReadyFn([this]{
				if(mStatusCallback) mStatusCallback(true);
			});
			mWebPlayer->getWeb()->setErrorCallback([this](const std::string& errorMsg){
				if(mErrorCallback) mErrorCallback(errorMsg);
			});
		}

		mContentAspectRatio = mWebPlayer->getWidth() / mWebPlayer->getHeight();
		contentWidth = mWebPlayer->getWidth();
		contentHeight = mWebPlayer->getHeight();


	} else {
		DS_LOG_WARNING("Whoopsies - tried to open a media player on an invalid file type. " << mResource.getAbsoluteFilePath() << " " << ds::utf8_from_wstr(mResource.getTypeName()));
	}


	if(showThumbnail && (mResource.getThumbnailId() > 0 || !mResource.getThumbnailFilePath().empty())){
		int flags = 0;
		if(mMediaViewerSettings.mCacheImages){
			flags |= Image::IMG_CACHE_F;
		}
		mThumbnailImage = new ds::ui::Image(mEngine);
		addChildPtr(mThumbnailImage);
		mThumbnailImage->sendToBack();
		if(mResource.getThumbnailId() > 0){
			mThumbnailImage->setImageResource(mResource.getThumbnailId(), flags);
		} else {
			mThumbnailImage->setImageFile(mResource.getThumbnailFilePath(), flags);
		}
		mThumbnailImage->setOpacity(0.0f);
		mThumbnailImage->setStatusCallback([this](ds::ui::Image::Status status){
			if(status.mCode == status.STATUS_LOADED && mThumbnailImage){
				mThumbnailImage->tweenOpacity(1.0f, mAnimDuration);
			}
		});
	}

	setSize(contentWidth, contentHeight);

	if(mInitializedCallback){
		mInitializedCallback();
	}
}
コード例 #14
0
ファイル: model_maker.cpp プロジェクト: hksonngan/ds_cinder
void ModelMaker::run() {
	if(mYamlFileLocation.length() < 1){
		DS_LOG_WARNING("No file specified in model maker");
		return;
	}

	std::cout << "Parsing yaml file: " << mYamlFileLocation << std::endl;

	mYamlLoadService.mFileLocation = mYamlFileLocation;
	mYamlLoadService.run();

	std::vector<ModelModel> models = mYamlLoadService.mOutput;

	if(models.empty()){
		DS_LOG_WARNING("No valid models loaded in model maker.");
		return;
	}

	for(auto it = models.begin(); it < models.end(); ++it){
		ModelModel& mm = (*it);

		// make the first letter of the table name uppercase
		std::string tableName = mm.getTableName();

		if(tableName.empty()){
			DS_LOG_WARNING("Model maker got a blank table!");
			continue;
		}
		std::transform(tableName.begin(), tableName.begin() + 1, tableName.begin(), ::toupper);

		// push all the nearby getters/setters/members into stringstreams
		// headers
		std::stringstream sCustomIncludes;
		std::stringstream sCustomForwardDeclares;
		std::stringstream sHeaderGetters;
		std::stringstream sHeaderSetters;

		// imps
		std::stringstream sCustomImpIncludes;
		std::stringstream sDataMembers;
		std::stringstream sCustomEmptyData;
		std::stringstream sImpGetters;
		std::stringstream sImpSetters;

		// strings for each column
		std::string thisHeaderGetter;
		std::string thisHeaderSetter;
		std::string thisEmptyData;
		std::string thisDataMember;
		std::string thisImpGetter;
		std::string thisImpSetter;

		std::map<std::string, std::string> dataMemberInitializers;

		// make all 'resource' flagged columns into proper resources
		for(auto mit = mm.getResourceColumns().begin(); mit < mm.getResourceColumns().end(); ++mit){
			for(auto cit = mm.getColumns().begin(); cit < mm.getColumns().end(); ++cit){

				// if this column is the resource one, set it's type to resource and move on
				if((*cit).getColumnName() == (*mit) && ((*cit).getType() == ModelColumn::Integer || (*cit).getType() == ModelColumn::UnsignedInt)) {
					ModelColumn* mc = const_cast<ModelColumn*>(&(*cit));
					if(mc){
						mc->setType(ModelColumn::Resource);
					}
					break;
				}
			}
		}

		// add special columns for all relations
		for(auto rit = mm.getRelations().begin(); rit < mm.getRelations().end(); ++rit){
			const ModelRelation& mr = (*rit);
			if(mr.getType() == ModelRelation::Invalid) continue;

			// create the class name out of the foreign table name, e.g. StoryRef
			std::string foreignTable = mr.getForeignKeyTable();
			std::transform(foreignTable.begin(), foreignTable.begin() + 1, foreignTable.begin(), ::toupper);
			std::stringstream foreignClass;
			foreignClass << foreignTable << "Ref";

			// create the empty data name from the class name. e.g. EMPTY_STORY or EMPTY_STORY_ELEMENT_VECTOR
			std::string foreignEmptyType = foreignClass.str();
			std::transform(foreignEmptyType.begin(), foreignEmptyType.end(), foreignEmptyType.begin(), ::toupper);
			std::stringstream foreignEmptyTypeFull;
			foreignEmptyTypeFull << foreignEmptyType;

			std::stringstream foreignDataType;

			if(mr.getType() == ModelRelation::Many){
				foreignEmptyTypeFull << "_VECTOR";
				foreignDataType << "std::vector<" << foreignClass.str() << ">";

				// the 'many' types need to have a header include
				sCustomIncludes << "#include \"" << getFileName(mr.getForeignKeyTable(), true) << "\"" << std::endl;
			} else {
				foreignDataType << foreignClass.str();

				// single types need to be forward declared to avoid circular refs
				sCustomForwardDeclares << "class " << foreignClass.str() << ";" << std::endl;
				sCustomImpIncludes << "#include \"" << getFileName(mr.getForeignKeyTable(), true) << "\"" << std::endl;
			}
			
			ModelColumn mc;
			mc.setColumnName(foreignClass.str());
			mc.setType(ModelColumn::Custom);
			mc.setCustomDataType(foreignDataType.str());
			mc.setCustomEmptyDataName(foreignEmptyTypeFull.str());
			mm.addColumn(mc);

		}


		// add the getters, setters, empty data and data members for each column to the stringstreams
		for(auto cit = mm.getColumns().begin(); cit < mm.getColumns().end(); ++cit){

			thisHeaderGetter = headerGetter;
			thisHeaderSetter = headerSetter;
			thisEmptyData = "";
			thisDataMember = dataMember;
			thisImpGetter = impGetter;
			thisImpSetter = impSetter;

			std::string dataType = "";

			const ModelColumn& mc = (*cit);

			// invalid columns get tossed
			if(mc.getType() == ModelColumn::Invalid){
				continue;

				// if it's an int, check for unsigned int too
			} else if(mc.getType() == ModelColumn::Integer || mc.getType() == ModelColumn::UnsignedInt){
				if(mc.getIsUnsigned()){
					dataType = uintDataType;
					thisEmptyData = "UINT";

				} else {
					dataType = intDataType;
					thisEmptyData = "INT";
				}

			} else if(mc.getType() == ModelColumn::Float){
				dataType = floatDataType;
				thisEmptyData = "FLOAT";

			} else if(mc.getType() == ModelColumn::String){
				dataType = stringDataType;
				thisEmptyData = "WSTRING";

			} else if(mc.getType() == ModelColumn::Resource){
				dataType = resourceDataType;
				thisEmptyData = "RESOURCE";

			} else if(mc.getType() == ModelColumn::Custom){
				dataType = mc.getCustomDataType();
				thisEmptyData = mc.getCustomEmptyDataName();
				sCustomEmptyData << "const " << mc.getCustomDataType() << " EMPTY_" << mc.getCustomEmptyDataName() << ";" << std::endl;
			}


			std::string columnName = mc.getColumnName();
			std::transform(columnName.begin(), columnName.begin() + 1, columnName.begin(), ::toupper);

			dataMemberInitializers[columnName] = thisEmptyData;

			thisImpGetter = replaceAllString(thisImpGetter, "EMPTYDATATYPE", thisEmptyData);

			thisHeaderGetter = replaceAllString(thisHeaderGetter, "DATA_TYPE", dataType);
			thisHeaderSetter = replaceAllString(thisHeaderSetter, "DATA_TYPE", dataType); 	
			thisDataMember = replaceAllString(thisDataMember, "DATA_TYPE", dataType);
			thisImpGetter = replaceAllString(thisImpGetter, "DATA_TYPE", dataType);
			thisImpSetter = replaceAllString(thisImpSetter, "DATA_TYPE", dataType);

			sHeaderGetters << replaceAllString(thisHeaderGetter, "ColumnName", columnName) << std::endl;
			sHeaderSetters << replaceAllString(thisHeaderSetter, "ColumnName", columnName) << std::endl;
			sDataMembers << replaceAllString(thisDataMember, "ColumnName", columnName) << std::endl;
			sImpGetters << replaceAllString(thisImpGetter, "ColumnName", columnName) << std::endl;
			sImpSetters << replaceAllString(thisImpSetter, "ColumnName", columnName) << std::endl;

		}

		// add initializers to empty data when Data() is constructed
		std::stringstream memberInitializers;
		bool firstInitializer = true;
		for(auto it = dataMemberInitializers.begin(); it != dataMemberInitializers.end(); ++it){
			if(firstInitializer){
				memberInitializers << "\t: m";
				firstInitializer = false;
			} else {
				memberInitializers << "\t, m";
			}

			memberInitializers << it->first << "(EMPTY_" << it->second << ")\n";
		}

		// add all the stringstreams to the header and put in the table name / model name
		std::string header = baseHeader;
		header = replaceAllString(header, "FORWARD_DECLARES", sCustomForwardDeclares.str());
		header = replaceAllString(header, "CUSTOM_INCLUDES", sCustomIncludes.str());
		header = replaceAllString(header, "COLUMN_GETTERS", sHeaderGetters.str());
		header = replaceAllString(header, "COLUMN_SETTERS", sHeaderSetters.str());
		header = replaceAllString(header, "TableName", tableName);

		//std::cout << std::endl << std::endl << header << std::endl << std::endl;


		std::string imp = baseCpp;
		imp = replaceAllString(imp, "CUSTOM_INCLUDES", sCustomImpIncludes.str());
		imp = replaceAllString(imp, "CUSTOM_EMPTY_DATA", sCustomEmptyData.str());
		imp = replaceAllString(imp, "INITIALIZE_DATA_MEMBERS", memberInitializers.str());
		imp = replaceAllString(imp, "DATA_MEMBERS", sDataMembers.str());
		imp = replaceAllString(imp, "IMP_GETTERS", sImpGetters.str());
		imp = replaceAllString(imp, "IMP_SETTERS", sImpSetters.str());
		imp = replaceAllString(imp, "TableName", tableName);

		//	std::cout << std::endl << std::endl << imp << std::endl << std::endl;


		// write out the header and implementation
		std::stringstream filename;
		filename << "%APP%/generated/" << getFileName(mm.getTableName(), true);

		std::cout << "Writing header to: " << filename.str() << std::endl;

		std::ofstream headerWriter;
		headerWriter.open(ds::Environment::expand(filename.str()));
		headerWriter << header;
		headerWriter.close();

		filename.str("");

		filename << "%APP%/generated/" << getFileName(mm.getTableName(), false);
		std::cout << "Writing implementation to: " << filename.str() << std::endl;


		std::ofstream impWriter;
		impWriter.open(ds::Environment::expand(filename.str()));
		impWriter << imp;
		impWriter.close();
	}
}
コード例 #15
0
void ScrollList::assignItems(){
	if(!mScrollArea || !mScrollableHolder) return;

	float y = mScrollArea->getScrollerPosition().y;
	float x = mScrollArea->getScrollerPosition().x;
	float scrollHeight = mScrollArea->getHeight();
	float scrollWidth = mScrollArea->getWidth();


	std::vector<int> needsSprite;

	// Look through all the placeholdser and find all the items that should be onscreen
	// push the offscreen sprites into the reserve vector
	for(auto it = mItemPlaceHolders.begin(), it2 = mItemPlaceHolders.end(); it != it2; ++it){
		float itemY = y + it->mY;
		float itemX = x + it->mX;

		if((mVerticalScrolling && ((itemY + mIncrementAmount > 0.0f) && (itemY < scrollHeight))) ||
			(!mVerticalScrolling && ((itemX + mIncrementAmount > 0.0f) && (itemX < scrollWidth)))
			){
			if(it->mAssociatedSprite){
				it->mAssociatedSprite->setPosition(it->mX, it->mY);
			} else {
				needsSprite.push_back(it - mItemPlaceHolders.begin());
			}
		} else {
			if(it->mAssociatedSprite){
				mReserveItems.push_back(it->mAssociatedSprite);
			}
			it->mAssociatedSprite = nullptr;
		}
	}

	// give all the placeholders that need a sprite
	for(auto it = needsSprite.begin(), it2 = needsSprite.end(); it != it2; ++it){
		ds::ui::Sprite* sprite = nullptr;
		if(!mReserveItems.empty()){
			sprite = mReserveItems.back();
			mReserveItems.pop_back();
		} else {
			if(mCreateItemCallback) sprite = mCreateItemCallback();
			if(sprite){
				sprite->setProcessTouchCallback([this](ds::ui::Sprite* sp, const ds::ui::TouchInfo& ti){ handleItemTouchInfo(sp, ti); });
				sprite->setTapCallback([this, sprite](ds::ui::Sprite* bs, const ci::Vec3f cent){
					Poco::Timestamp::TimeVal nowwwy = Poco::Timestamp().epochMicroseconds();
					float timeDif = (float)(nowwwy - mLastUpdateTime) / 1000000.0f;
					if(timeDif < 0.2f){
						//DS_LOG_INFO("Too soon since the last touch to tap this list!");
						return;
					}
					if(mItemTappedCallback) mItemTappedCallback(sprite, cent);
				});
				mScrollableHolder->addChildPtr(sprite);
			} else {
				DS_LOG_WARNING("Didn't create a sprite for scroll list! Use the callback and make sprites when we need them!!");
			}
		}

		auto &placeHolder = mItemPlaceHolders[*it];

		if(sprite){

			if(mSetDataCallback) mSetDataCallback(sprite, placeHolder.mDbId);
			sprite->setPosition(placeHolder.mX, placeHolder.mY);
			sprite->show();
			placeHolder.mAssociatedSprite = sprite;
		}
	}

	// hide any extras
	for(auto it = mReserveItems.begin(), it2 = mReserveItems.end(); it != it2; ++it){
		auto sprite = *it;
		sprite->hide();
	}

}