⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 time_node.cpp

📁 彩信浏览器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	time_mset begin_list;	get_instance_times(m_begin_list, begin_list);	if(m_begin_event_inst != time_type::unresolved) {		begin_list.insert(m_begin_event_inst);		m_begin_event_inst = time_type::unresolved;	}		// Get the end instance list	time_mset end_list;	get_instance_times(m_end_list, end_list);		// Parent simple dur	time_type parent_simple_dur = up()?up()->get_last_dur():time_type::indefinite;		return m_time_calc->calc_next_interval(begin_list, end_list, parent_simple_dur, prev.end, 		prev.is_zero_dur());}// Sets the state of this node.// timestamp: "scheduled now" in parent simple time// This is the state change hook for this node.void time_node::set_state(time_state_type state, qtime_type timestamp, time_node *oproot) {	if(m_state->ident() == state) return;	m_state->exit(timestamp, oproot);	m_state = m_time_states[state];	m_state->enter(timestamp);}// Calls set_state() after checking for exclvoid time_node::set_state_ex(time_state_type tst, qtime_type timestamp) {	// this should be true	assert(timestamp.first == sync_node());		if(sync_node()->is_excl()) {		excl *p = static_cast<excl*>(sync_node());		if(tst == ts_active) {			p->interrupt(this, timestamp);		} else if(tst == ts_postactive) {			set_state(tst, timestamp, this);			p->on_child_normal_end(this, timestamp);		}		return;	}	set_state(tst, timestamp, this);}// Cancels the current interval notifyings dependents.void time_node::cancel_interval(qtime_type timestamp) {	AM_DBG m_logger->debug("%s[%s].cancel_interval(): %s", m_attrs.get_tag().c_str(), 		m_attrs.get_id().c_str(), ::repr(m_interval).c_str());		assert(m_interval.is_valid());		// The interval should be updated before sync_update 	// to make available the new info to induced calcs	interval_type i = m_interval;	m_interval = interval_type::unresolved;			on_cancel_instance(timestamp, tn_begin, i.begin);	on_cancel_instance(timestamp, tn_end, i.end);}// Updates the current interval with the one provided notifyings dependents.void time_node::update_interval(qtime_type timestamp, const interval_type& new_interval) {	AM_DBG m_logger->debug("%s[%s].update_interval(): %s -> %s", m_attrs.get_tag().c_str(), 		m_attrs.get_id().c_str(), ::repr(m_interval).c_str(), ::repr(new_interval).c_str());		assert(m_interval.is_valid());	assert(timestamp.first == sync_node());		// The interval should be updated before sync_update 	// to make available the new info to induced calcs	interval_type old = m_interval;	m_interval = new_interval;			if(m_interval.begin != old.begin) {		time_type dt = m_interval.begin - timestamp.second;		qtime_type qt(sync_node(), m_interval.begin);		on_update_instance(timestamp, tn_begin, m_interval.begin, old.begin);		raise_update_event(timestamp);	} 	if(m_interval.end != old.end) {		time_type dt = m_interval.end - timestamp.second;		if(dt.is_definite()) {			// Sync node is probably interested for this event.			sync_node()->raise_update_event(timestamp);		}		on_update_instance(timestamp, tn_end, m_interval.end, old.end);	}}// Updates the current interval end with the value provided notifyings dependents.void time_node::update_interval_end(qtime_type timestamp, time_type new_end) {	AM_DBG m_logger->debug("%s[%s].update_interval_end(): %s -> %s at PT:%ld, DT:%ld", 		m_attrs.get_tag().c_str(), m_attrs.get_id().c_str(), 		::repr(m_interval.end).c_str(), 		::repr(new_end).c_str(), 		timestamp.second(),		timestamp.as_doc_time_value());		if(!m_interval.is_valid()) return;		time_type old_end = m_interval.end;		// The interval should be updated before sync_update 	// to make available the new info to induced calcs	m_interval.end = new_end;		on_update_instance(timestamp, tn_end, new_end, old_end);		// Sync node is probably interested for this event.	if(up()) up()->raise_update_event(timestamp);}// Sets a new interval as current, updates dependents and schedules activation.// After this call the state of the node // a) Remains the same (proactive or postactive) if the interval is after timestamp.//    In this case the interval is scheduled.// b) Transitions to postactive if the interval is before timestamp// c) Transitions to active if the interval contains timestamp// See active_state::enter() for the activities executed// when the node is activated.// param timestamp: "now" in parent simple timevoid time_node::set_interval(qtime_type timestamp, const interval_type& i) {	AM_DBG m_logger->debug("%s[%s].set_current_interval(): %s (DT=%ld)", m_attrs.get_tag().c_str(), 		m_attrs.get_id().c_str(), ::repr(i).c_str(), timestamp.as_doc_time_value());		// verify the assumptions made in the following code	assert(timestamp.first == sync_node());	assert(m_state->ident() == ts_proactive || m_state->ident() == ts_postactive);	assert(is_root() || up()->m_state->ident() == ts_active);	if(!can_set_interval(timestamp, i)) {		raise_update_event(timestamp);		return;	}		// Set the interval as current.	m_interval = i;		// Update dependents, event if this interval will never play	on_new_instance(timestamp, tn_begin, m_interval.begin);	on_new_instance(timestamp, tn_end, m_interval.end);	// Update parent to recalc end sync status	if(sync_node()->is_par() || sync_node()->is_excl())		sync_node()->raise_update_event(timestamp);		// Is this a cut-off interval?	// this can happen when proactive	if(m_interval.before(timestamp.second)) {				assert(m_state->ident() == ts_proactive);				// Add to history and invalidate		played_interval(timestamp);				// Jump to post active		set_state(ts_postactive, timestamp, this);				return; 	}			if(m_interval.after(timestamp.second)) {		// Schedule activation: 		// activate at m_interval.begin - timestamp		return; 	}		// Else, the interval should be activated now	assert(m_interval.contains(timestamp.second));	if(deferred()) defer_interval(timestamp);	else set_state_ex(ts_active, timestamp);}// Returns true when the node can establish its interval// Fixes biased intervals// The design should be improved so that this function always returns true. bool time_node::can_set_interval(qtime_type timestamp, const interval_type& i) {	if(is_root() || i.after(timestamp.second)) return true;	if(up() && up()->is_seq()) {		// the node should go active but the interval may be wrong/biased		 time_node *prev = previous();		 if(prev && prev->is_active()) {			// wait			AM_DBG m_logger->debug("%s[%s] attempt to set_current_interval() but prev active: %s (DT=%ld)", m_attrs.get_tag().c_str(), 				m_attrs.get_id().c_str(), ::repr(i).c_str(), timestamp.as_doc_time_value());			return false;		 }	}	// if an ancestor is paused or deferred return false	std::list<const time_node*> path;	get_path(path);	std::list<const time_node*>::reverse_iterator it = path.rbegin();	it++; // pass over this	for(;it!=path.rend();it++) {		const time_node *atn = (*it);		if(atn->paused() || atn->deferred()) {			AM_DBG {				std::string astate;				if(atn->paused()) astate = "paused";				else if(atn->deferred()) astate = "deferred";				m_logger->debug("%s[%s] attempt to set_current_interval() but an ancestor is %s: %s (DT=%ld)", 					m_attrs.get_tag().c_str(), m_attrs.get_id().c_str(), astate.c_str(),					::repr(i).c_str(), timestamp.as_doc_time_value());			}			return false;		}	}	return true;}// Add to history and invalidate the current intervalvoid time_node::played_interval(qtime_type timestamp) {	m_history.push_back(m_interval);	q_smil_time b(sync_node(), m_interval.begin);	q_smil_time e(sync_node(), m_interval.end);	m_doc_history.push_back(interval_type(b.as_doc_time(), e.as_doc_time()));	m_interval = interval_type::unresolved;}// Returns the first interval played by this node.// Returns an invalid interval when this node has not played.const time_node::interval_type& time_node::get_first_interval(bool asdoc /* = false*/) const {	if(asdoc) {		if(!m_doc_history.empty())			return m_doc_history.front();		return interval_type::unresolved;	}	if(!m_history.empty())		return m_history.front();	return m_interval;}// Returns the last interval associated with this (can be invalid)const time_node::interval_type& time_node::get_last_interval() const {	if(m_interval.is_valid())		return m_interval;	if(!m_history.empty())		return m_history.back();	return m_interval;}// Activates the interval of this node.// This function is one of the activities executed when a node enters the active state.// See active_state::enter() function for the complete list of activities.  //// timestamp: "scheduled now" in parent simple timevoid time_node::activate(qtime_type timestamp) {	// verify the assumptions made in the following code	assert(timestamp.first == sync_node());	if(!m_interval.contains(timestamp.second))		set_state(ts_postactive, timestamp, this);	assert(timestamp.second >= 0);			// We need to convert parent's simple time to this node's simple time.	// For this convertion we need the dur since,	// t_p = t_c + rad_c + begin_c  => rad_c + t_c = t_p - begin_c	// => t_c = rem(t_p - begin_c, dur) and rad_c = mod(t_p - begin_c, dur)*dur		// The offset we are now within the current interval	time_type ad_offset = timestamp.second - m_interval.begin;		// The simple duration of this node	time_type cdur = calc_dur();		// Calculate the offset within the simple duration	// that this node should start playing.	time_type sd_offset = 0;	if(ad_offset == 0) {		sd_offset = 0;	} else if(!cdur.is_definite()) {		sd_offset = ad_offset;	} else if(cdur == 0) {		sd_offset = 0;	} else {		sd_offset = ad_offset.rem(cdur);				// In this case we need to update the values of the repeat registers.		// Previous values: m_rad(0), m_precounter(0)				// The current repeat index		m_precounter = ad_offset.mod(cdur);				// The accumulated repeat interval.		m_rad = m_precounter*cdur();			}		AM_DBG m_logger->debug("%s[%s].start(%ld) ST:%ld, PT:%ld, DT:%ld", m_attrs.get_tag().c_str(), 		m_attrs.get_id().c_str(),  sd_offset(), sd_offset(),		timestamp.second(),		timestamp.as_doc_time_value());			// Adjust timer	if(m_timer) {		m_timer->set_time(ad_offset());		m_timer->set_speed(m_attrs.get_speed());	}		// Start node	if(!paused()) {		if(is_animation()) start_animation(sd_offset);		else start_playable(sd_offset);		if(m_timer) m_timer->resume();	}}// Starts an animationvoid time_node::start_animation(time_type offset) {	qtime_type timestamp(this, offset);	AM_DBG m_logger->debug("%s[%s].start_animation(%ld) DT:%ld", m_attrs.get_tag().c_str(), 		m_attrs.get_id().c_str(), offset(), timestamp.as_doc_time_value());	animation_engine *ae = m_context->get_animation_engine();	animate_node *an = (animate_node*)this;	an->prepare_interval();	ae->started(an);}// Stops an animationvoid time_node::stop_animation() {	animation_engine *ae = m_context->get_animation_engine();	ae->stopped((animate_node*)this);}// Returns true when this node is associated with a playablebool time_node::is_playable() const {	return !is_time_container() && !is_animation();}// Returns true when this node is an animationbool time_node::is_animation() const {	return common::schema::get_instance()->is_animation(m_node->get_qname());}//////////////////////////// Playables shellvoid time_node::start_playable(time_type offset) {	if(m_ffwd_mode) {		AM_DBG m_logger->debug("start_playable(%ld): ffwd skip %s", offset(), get_sig().c_str());		return;	}	if(!is_playable() ) {		return;	}	qtime_type timestamp(this, offset);	AM_DBG m_logger->debug("%s[%s].start_playable(%ld) DT:%ld", m_attrs.get_tag().c_str(), 		m_attrs.get_id().c_str(), offset(), timestamp.as_doc_time_value());	m_eom_flag = false;	common::playable *np = create_playable();	if(np) np->wantclicks(m_want_activate_events);	const lib::transition_info *trans_in = m_attrs.get_trans_in();	if(np) {		if(trans_in) {			m_context->start_playable(m_node, time_type_to_secs(offset()), trans_in);		} else {			np->start(time_type_to_secs(offset()));		} 	}	if (is_link()  && m_attrs.get_actuate() == actuate_onload) {		AM_DBG m_logger->debug("%s[%s].start_playable: actuate_onLoad", m_attrs.get_tag().c_str(), 			m_attrs.get_id().c_str());		follow_link(timestamp);	}}void time_node::seek_playable(time_type offset) {	if(!is_playable() || m_ffwd_mode) return;	AM_DBG m_logger->debug("%s[%s].seek(%ld)", m_attrs.get_tag().c_str(), 		m_attrs.get_id().c_str(), offset());	m_context->seek_playable(m_node, time_type_to_secs(offset()));}void time_node::pause_playable(common::pause_display d) {	if(!is_playable() || m_ffwd_mode) return;	AM_DBG m_logger->debug("%s[%s].pause()", m_attrs.get_tag().c_str(), 		m_attrs.get_id().c_str());	m_context->pause_playable(m_node, d);}void time_node::resume_playable() {	if(!is_playable() || m_ffwd_mode) return;	m_logger->debug("%s[%s].resume()", m_attrs.get_tag().c_str(), 		m_attrs.get_id().c_str());	m_context->resume_playable(m_node);}void time_node::stop_playable() {	if(!is_playable()) return;	if(!m_needs_remove) return;	m_eom_flag = true;	AM_DBG m_logger->debug("%s[%s].stop()", m_attrs.get_tag().c_str(), 		m_attrs.get_id().c_str());	m_context->stop_playable(m_node);}void time_node::repeat_playable() {	if(!is_playable() || m_ffwd_mode) return;	AM_DBG m_logger->debug("%s[%s].repeat()", m_attrs.get_tag().c_str(), 		m_attrs.get_id().c_str());	m_context->start_playable(m_node, 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -