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

📄 smil_player.cpp

📁 彩信浏览器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// This file is part of Ambulant Player, www.ambulantplayer.org.//// Copyright (C) 2003-2007 Stichting CWI, // Kruislaan 413, 1098 SJ Amsterdam, The Netherlands.//// Ambulant Player is free software; you can redistribute it and/or modify// it under the terms of the GNU Lesser General Public License as published by// the Free Software Foundation; either version 2.1 of the License, or// (at your option) any later version.//// Ambulant Player is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with Ambulant Player; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA#include "ambulant/lib/document.h"#include "ambulant/lib/node.h"#include "ambulant/lib/logger.h"#include "ambulant/lib/gtypes.h"#include "ambulant/lib/event.h"#include "ambulant/lib/callback.h"#include "ambulant/lib/system.h"#include "ambulant/lib/transition_info.h"#include "ambulant/common/factory.h"#include "ambulant/common/layout.h"#include "ambulant/common/schema.h"#include "ambulant/smil2/smil_time.h"#include "ambulant/smil2/test_attrs.h"#include "ambulant/smil2/smil_player.h"#include "ambulant/smil2/timegraph.h"#include "ambulant/smil2/smil_layout.h"#include "ambulant/smil2/time_sched.h"#include "ambulant/smil2/animate_e.h"#ifndef AM_DBG#define AM_DBG if(0)#endifusing namespace ambulant;using namespace smil2;common::player *common::create_smil2_player(	lib::document *doc,	common::factories* factory,	common::embedder *sys){	return new smil_player(doc, factory, sys);}smil_player::smil_player(lib::document *doc, common::factories *factory, common::embedder *sys):	m_doc(doc),	m_factory(factory),	m_system(sys),	m_feedback_handler(0),	m_animation_engine(0),	m_root(0),	m_dom2tn(0),	m_layout_manager(0),	m_timer(new timer_control_impl(realtime_timer_factory(), 1.0, false)),	m_event_processor(0),	m_scheduler(0),	m_state(common::ps_idle),	m_cursorid(0), 	m_pointed_node(0), 	m_wait_for_eom_flag(true),	m_focus(0),	m_focussed_nodes(new std::set<int>()),	m_new_focussed_nodes(0){		m_logger = lib::logger::get_logger();	AM_DBG m_logger->debug("smil_player::smil_player(0x%x)", this);}voidsmil_player::initialize(){	document_loaded(m_doc);		m_event_processor = event_processor_factory(m_timer);	// build the layout (we need the top-level layout)	build_layout();	// Build the timegraph using the current filter	build_timegraph();	m_layout_manager->load_bgimages(m_factory);}smil_player::~smil_player() {	AM_DBG m_logger->debug("smil_player::~smil_player(0x%x)", this);		// sync destruction	m_timer->pause();	cancel_all_events();	m_timer->pause();	cancel_all_events();			m_scheduler->reset_document();	std::map<const lib::node*, common::playable *>::iterator it;	for(it = m_playables.begin();it!=m_playables.end();it++) {		int rem = (*it).second->release();		if (rem) m_logger->trace("smil_player::~smil_player: playable 0x%x still has refcount of %d", (*it).second, rem);	}		delete m_focussed_nodes;	delete m_new_focussed_nodes;	delete m_event_processor;	delete m_timer;	delete m_dom2tn;	delete m_animation_engine;	delete m_root;	delete m_scheduler;//	delete m_doc;	delete m_layout_manager;}void smil_player::build_layout() {	if(m_state != common::ps_idle && m_state != common::ps_done)		return;	if(m_layout_manager) {		delete m_layout_manager;		delete m_animation_engine;	}	m_layout_manager = new smil_layout_manager(m_factory, m_doc);	m_animation_engine = new animation_engine(m_event_processor, m_layout_manager);}void smil_player::build_timegraph() {	if(m_state != common::ps_idle && m_state != common::ps_done)		return;	if(m_root) {		delete m_root;		delete m_dom2tn;		delete m_scheduler;	}	timegraph tg(this, m_doc, schema::get_instance());	m_root = tg.detach_root();	m_dom2tn = tg.detach_dom2tn();	m_scheduler = new scheduler(m_root, m_timer);}void smil_player::schedule_event(lib::event *ev, lib::timer::time_type t, event_priority ep) {	m_event_processor->add_event(ev, t, ep);}// Command to start playbackvoid smil_player::start() {	if(m_state == common::ps_pausing) {		resume();	} else if(m_state == common::ps_idle || m_state == common::ps_done) {		if(!m_root) build_timegraph();		if(m_root) {			if (m_system) m_system->starting(this);			m_scheduler->start(m_root);			update();		}	}}// Command to stop playbackvoid smil_player::stop() {	if(m_state != common::ps_pausing && m_state != common::ps_playing)		return;	m_timer->pause();	cancel_all_events();			m_scheduler->reset_document();	done_playback();}// Command to pause playbackvoid smil_player::pause() {	if(m_state != common::ps_playing)		return;		m_state = common::ps_pausing;	m_timer->pause();	std::map<const lib::node*, common::playable *>::iterator it;	for(it = m_playables.begin();it!=m_playables.end();it++)		(*it).second->pause();}// Command to resume playbackvoid smil_player::resume() {	if(m_state != common::ps_pausing)		return;		m_state = common::ps_playing;	std::map<const lib::node*, common::playable *>::iterator it;	for(it = m_playables.begin();it!=m_playables.end();it++)		(*it).second->resume();	m_timer->resume();}// Started callback from the schedulervoid smil_player::started_playback() {	m_state = common::ps_playing;	document_started();}// Done callback from the schedulervoid smil_player::done_playback() {	m_state = common::ps_done;	m_timer->pause();	document_stopped();	if(m_system) 		m_system->done(this);}// Request to create a playable for the node.common::playable *smil_player::create_playable(const lib::node *n) {	std::map<const lib::node*, common::playable *>::iterator it = 		m_playables.find(n);	common::playable *np = (it != m_playables.end())?(*it).second:0;	if(np == NULL) {		np = new_playable(n);AM_DBG lib::logger::get_logger()->debug("smil_player::create_playable(0x%x)cs.enter", (void*)n);		m_playables_cs.enter();		m_playables[n] = np;		m_playables_cs.leave();AM_DBG lib::logger::get_logger()->debug("smil_player::create_playable(0x%x)cs.leave", (void*)n);	}		// We also need to remember any accesskey attribute (as opposed to accesskey	// value for a timing attribute) because these are global.	// XXX It may be better/cheaper if we simply iterate over the m_playables....	const char *accesskey = n->get_attribute("accesskey");	if (accesskey) {		int nid = n->get_numid();		// XXX Is this unicode-safe?		m_accesskey_map[accesskey[0]] = nid;	}	return np;}// Request to start the playable of the node.// When trans is not null the playable should transition in void smil_player::start_playable(const lib::node *n, double t, const lib::transition_info *trans) {	AM_DBG lib::logger::get_logger()->debug("smil_player::start_playable(0x%x, %f)", (void*)n, t);	common::playable *np = create_playable(n);	if (trans) {		common::renderer *rend = np->get_renderer();		if (!rend) {			const char *pid = n->get_attribute("id");			m_logger->trace("smil_player::start_playable: node %s has transition but is not visual", pid?pid:"no-id");		} else {			rend->set_intransition(trans);		}	}	np->start(t);}// Request to seek the playable of the node.void smil_player::seek_playable(const lib::node *n, double t) {	AM_DBG lib::logger::get_logger()->debug("smil_player::seek_playable(0x%x, %f)", (void*)n, t);	common::playable *np = create_playable(n);	np->seek(t);}// Request to start a transition of the playable of the node.void smil_player::start_transition(const lib::node *n, const lib::transition_info *trans, bool in) {	AM_DBG lib::logger::get_logger()->debug("smil_player::start_transition(0x%x, -x%x, in=%d)", (void*)n, trans, in);	std::map<const lib::node*, common::playable *>::iterator it = 		m_playables.find(n);	common::playable *np = (it != m_playables.end())?(*it).second:0;	if(!np) {		const char *pid = n->get_attribute("id");		m_logger->debug("smil_player::start_transition: node %s has no playable", pid?pid:"no-id");		return;	}	common::renderer *rend = np->get_renderer();	if (!rend) {		const char *pid = n->get_attribute("id");		m_logger->trace("smil_player::start_transition: node %s has transition but is not visual", pid?pid:"no-id");	} else {		if (in) {			// XXX Jack thinks there's no reason for this...			AM_DBG m_logger->debug("smil_player::start_transition: called for in-transition");			rend->set_intransition(trans);		} else {			rend->start_outtransition(trans);		}	}}// Request to stop the playable of the node.void smil_player::stop_playable(const lib::node *n) {	AM_DBG lib::logger::get_logger()->debug("smil_player::stop_playable(0x%x)", (void*)n);	if (n == m_focus) {		m_focus = NULL;		highlight(n, false);		node_focussed(NULL);	}AM_DBG lib::logger::get_logger()->debug("smil_player::stop_playable(0x%x)cs.enter", (void*)n);	m_playables_cs.enter();			std::map<const lib::node*, common::playable *>::iterator it = 		m_playables.find(n);	std::pair<const lib::node*, common::playable*> victim(NULL,NULL);	if(it != m_playables.end()) {#ifdef AMBULANT_PLATFORM_WIN32_WCE		victim = std::pair<const lib::node*, common::playable*>((*it).first, (*it).second);#else		victim = *it;#endif		m_playables.erase(it);	}	m_playables_cs.leave();	if (victim.first)		destroy_playable(victim.second, victim.first);AM_DBG lib::logger::get_logger()->debug("smil_player::stop_playable(0x%x)cs.leave", (void*)n);}// Request to pause the playable of the node.void smil_player::pause_playable(const lib::node *n, pause_display d) {	AM_DBG lib::logger::get_logger()->debug("smil_player::pause_playable(0x%x)", (void*)n);	common::playable *np = get_playable(n);	if(np) np->pause(d);}// Request to resume the playable of the node.void smil_player::resume_playable(const lib::node *n) {	AM_DBG lib::logger::get_logger()->debug("smil_player::resume_playable(0x%xf)", (void*)n);	common::playable *np = get_playable(n);	if(np) np->resume();}// Query the node's playable for its duration.common::duration smil_player::get_dur(const lib::node *n) {	const common::duration not_available(false, 0.0);	std::map<const lib::node*, common::playable *>::iterator it = 		m_playables.find(n);	common::playable *np = (it != m_playables.end())?(*it).second:0;	if(np) {		common::duration idur = np->get_dur();		if(idur.first) m_playables_dur[n] = idur.second;		AM_DBG lib::logger::get_logger()->debug("smil_player::get_dur(0x%x): <%s, %f>", n, idur.first?"true":"false", idur.second);		return idur;	}	std::map<const node*, double>::iterator it2 = m_playables_dur.find(n);	common::duration rv = (it2 != m_playables_dur.end())?common::duration(true,(*it2).second):not_available;	AM_DBG lib::logger::get_logger()->debug("smil_player::get_dur(0x%x): <%s, %f>", n, rv.first?"true":"false", rv.second);	return rv;}// Notify the playable that it should update this on user events (click, point).void smil_player::wantclicks_playable(const lib::node *n, bool want) {	common::playable *np = get_playable(n);	if(np) np->wantclicks(want);}// Playable notification for a click event.void smil_player::clicked(int n, double t) {	AM_DBG m_logger->debug("smil_player::clicked(%d, %f)", n, t);	typedef lib::scalar_arg_callback_event<time_node, q_smil_time> dom_event_cb;	std::map<int, time_node*>::iterator it = m_dom2tn->find(n);	if(it != m_dom2tn->end() && (*it).second->wants_activate_event()) {		time_node::value_type root_time = m_root->get_simple_time();		m_scheduler->update_horizon(root_time);		q_smil_time timestamp(m_root, root_time);		dom_event_cb *cb = new dom_event_cb((*it).second, 			&time_node::raise_activate_event, timestamp);		schedule_event(cb, 0, ep_high);		m_scheduler->exec();	}}voidsmil_player::before_mousemove(int cursorid){	m_cursorid = cursorid;	delete m_new_focussed_nodes;	m_new_focussed_nodes = new std::set<int>();	AM_DBG m_logger->debug("smil_player(0x%x)::before_mousemove(%d) m_new_focussed_nodes=0x%x", this, cursorid, m_new_focussed_nodes);}intsmil_player::after_mousemove(){	typedef lib::scalar_arg_callback_event<time_node, q_smil_time> dom_event_cb;	std::set<int>::iterator i;	m_pointed_node = 0;	// First we send outOfBounds and focusOut events to all	// the nodes that were in the focus but no longer are.	for (i=m_focussed_nodes->begin(); i!=m_focussed_nodes->end(); i++) {		int n = *i;				// If the node is also in the new focus we're done.		if (m_new_focussed_nodes->count(n) > 0) continue;				// If the node can't be found we're done.		std::map<int, time_node*>::iterator it = m_dom2tn->find(n);		if (it == m_dom2tn->end()) continue;				// Otherwise we send it outofbounds and focusout events, if it is interested.		time_node *tn = (*it).second;		AM_DBG m_logger->debug("after_mousemove: focus lost by %d, 0x%x", n, tn);				if (tn->wants_outofbounds_event()) {			AM_DBG m_logger->debug("smil_player::pointed: schedule 0x%x.outOfBoundsEvent", (void*)tn);			time_node::value_type root_time = m_root->get_simple_time();			m_scheduler->update_horizon(root_time);			q_smil_time timestamp(m_root, root_time);			dom_event_cb *cb = new dom_event_cb(tn, 				&time_node::raise_outofbounds_event, timestamp);			schedule_event(cb, 0, ep_high);		}		if (tn->wants_focusout_event()) {			AM_DBG m_logger->debug("smil_player::pointed: schedule 0x%x.focusOutEvent", (void*)tn);			time_node::value_type root_time = m_root->get_simple_time();			m_scheduler->update_horizon(root_time);			q_smil_time timestamp(m_root, root_time);			dom_event_cb *cb = new dom_event_cb(tn, 				&time_node::raise_focusout_event, timestamp);			schedule_event(cb, 0, ep_high);		}	}		// Next we send inbound and focusin events to the nodes that	// are now in the focus, and were not there before.	for (i=m_new_focussed_nodes->begin(); i!=m_new_focussed_nodes->end(); i++) {

⌨️ 快捷键说明

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