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

📄 gameswf_action.h

📁 一个开源的Flash 播放器,可以在Windows/Linux 上运行
💻 H
📖 第 1 页 / 共 2 页
字号:
// gameswf_action.h	-- Thatcher Ulrich <tu@tulrich.com> 2003// This source code has been donated to the Public Domain.  Do// whatever you want with it.// Implementation and helpers for SWF actions.#ifndef GAMESWF_ACTION_H#define GAMESWF_ACTION_H#include "gameswf.h"#include "gameswf_types.h"#include <wchar.h>#include "base/container.h"#include "base/smart_ptr.h"namespace gameswf{	struct movie;	struct as_environment;	struct as_object_interface;	struct as_value;	struct as_as_function;	//	// event_id	//	// For keyDown and stuff like that.	struct event_id	{		// These must match the function names in event_id::get_function_name()		enum id_code		{			INVALID,			// These are for buttons & sprites.			PRESS,			RELEASE,			RELEASE_OUTSIDE,			ROLL_OVER,			ROLL_OUT,			DRAG_OVER,			DRAG_OUT,			KEY_PRESS,			// These are for sprites only.			INITIALIZE,			LOAD,			UNLOAD,			ENTER_FRAME,			MOUSE_DOWN,			MOUSE_UP,			MOUSE_MOVE,			KEY_DOWN,			KEY_UP,			DATA,			                        // These are for the MoveClipLoader ActionScript only                        LOAD_START,                        LOAD_ERROR,                        LOAD_PROGRESS,                        LOAD_INIT,			                        // These are for the XMLSocket ActionScript only                        SOCK_CLOSE,                        SOCK_CONNECT,                        SOCK_DATA,                        SOCK_XML,			                        // These are for the XML ActionScript only                        XML_LOAD,                        XML_DATA,			                        // This is for setInterval                        TIMER,						EVENT_COUNT		};		unsigned char	m_id;		unsigned char	m_key_code;		event_id() : m_id(INVALID), m_key_code(key::INVALID) {}		event_id(id_code id, key::code c = key::INVALID)			:			m_id((unsigned char) id),			m_key_code((unsigned char) c)		{			// For the button key events, you must supply a keycode.			// Otherwise, don't.			assert((m_key_code == key::INVALID && (m_id != KEY_PRESS))				|| (m_key_code != key::INVALID && (m_id == KEY_PRESS)));		}		bool	operator==(const event_id& id) const { return m_id == id.m_id && m_key_code == id.m_key_code; }		// Return the name of a method-handler function corresponding to this event.		const tu_string&	get_function_name() const;	};	//	// with_stack_entry	//	// The "with" stack is for Pascal-like with-scoping.	struct with_stack_entry	{		smart_ptr<as_object_interface>	m_object;		int	m_block_end_pc;				with_stack_entry()			:			m_object(NULL),			m_block_end_pc(0)		{		}		with_stack_entry(as_object_interface* obj, int end)			:			m_object(obj),			m_block_end_pc(end)		{		}	};	// Base class for actions.	struct action_buffer	{		action_buffer();		void	read(stream* in);		void	execute(as_environment* env);		void	execute(			as_environment* env,			int start_pc,			int exec_bytes,			as_value* retval,			const array<with_stack_entry>& initial_with_stack,			bool is_function2);		bool	is_null()		{			return m_buffer.size() < 1 || m_buffer[0] == 0;		}		int	get_length() const { return m_buffer.size(); }	private:		// Don't put these as values in array<>!  They contain		// internal pointers and cannot be moved or copied.		// If you need to keep an array of them, keep pointers		// to new'd instances.		action_buffer(const action_buffer& a) { assert(0); }		void operator=(const action_buffer& a) { assert(0); }		void	process_decl_dict(int start_pc, int stop_pc);		// data:		array<unsigned char>	m_buffer;		array<const char*>	m_dictionary;		int	m_decl_dict_processed_at;	};	struct fn_call;	typedef void (*as_c_function_ptr)(const fn_call& fn);	struct as_property_interface	{		virtual bool	set_property(int index, const as_value& val) = 0;	};	// ActionScript value type.	struct as_value	{		enum type		{			UNDEFINED,			NULLTYPE,			BOOLEAN,			STRING,			NUMBER,			OBJECT,			C_FUNCTION,			AS_FUNCTION,	// ActionScript function.		};		type	m_type;		mutable tu_string	m_string_value;		union		{			bool m_boolean_value;			// @@ hm, what about PS2, where double is bad?  should maybe have int&float types.			mutable	double	m_number_value;			as_object_interface*	m_object_value;			as_c_function_ptr	m_c_function_value;			as_as_function*	m_as_function_value;		};		as_value()			:			m_type(UNDEFINED),			m_number_value(0.0)		{		}		as_value(const as_value& v)			:			m_type(UNDEFINED),			m_number_value(0.0)		{			*this = v;		}		as_value(const char* str)			:			m_type(STRING),			m_string_value(str),			m_number_value(0.0)		{		}		as_value(const wchar_t* wstr)			:			m_type(STRING),			m_string_value(""),			m_number_value(0.0)		{			// Encode the string value as UTF-8.			//			// Is this dumb?  Alternatives:			//			// 1. store a tu_wstring instead of tu_string?			// Bloats typical ASCII strings, needs a			// tu_wstring type, and conversion back the			// other way to interface with char[].			// 			// 2. store a tu_wstring as a union with			// tu_string?  Extra complexity.			//			// 3. ??			//			// Storing UTF-8 seems like a pretty decent			// way to do it.  Everything else just			// continues to work.#if (WCHAR_MAX != MAXINT)			tu_string::encode_utf8_from_wchar(&m_string_value, (const uint16 *)wstr);#else# if (WCHAR_MAX != MAXSHORT)# error "Can't determine the size of wchar_t"# else			tu_string::encode_utf8_from_wchar(&m_string_value, (const uint32 *)wstr);# endif#endif		}		as_value(bool val)			:			m_type(BOOLEAN),			m_boolean_value(val)		{		}		as_value(int val)			:			m_type(NUMBER),			m_number_value(double(val))		{		}		as_value(float val)			:			m_type(NUMBER),			m_number_value(double(val))		{		}		as_value(double val)			:			m_type(NUMBER),			m_number_value(val)		{		}		as_value(as_object_interface* obj);		as_value(as_c_function_ptr func)			:			m_type(C_FUNCTION),			m_c_function_value(func)		{			m_c_function_value = func;		}		as_value(as_as_function* func);		~as_value() { drop_refs(); }		// Useful when changing types/values.		void	drop_refs();		type	get_type() const { return m_type; }		// Return true if this value is callable.		bool is_function() const		{			return m_type == C_FUNCTION || m_type == AS_FUNCTION;		}		const char*	to_string() const;		const tu_string&	to_tu_string() const;		const tu_string&	to_tu_string_versioned(int version) const;		const tu_stringi&	to_tu_stringi() const;		double	to_number() const;		bool	to_bool() const;		as_object_interface*	to_object() const;		as_c_function_ptr	to_c_function() const;		as_as_function*	to_as_function() const;		void	convert_to_number();		void	convert_to_string();		void	convert_to_string_versioned(int version);		// These set_*()'s are more type-safe; should be used		// in preference to generic overloaded set().  You are		// more likely to get a warning/error if misused.		void	set_tu_string(const tu_string& str) { drop_refs(); m_type = STRING; m_string_value = str; }		void	set_string(const char* str) { drop_refs(); m_type = STRING; m_string_value = str; }		void	set_double(double val) { drop_refs(); m_type = NUMBER; m_number_value = val; }		void	set_bool(bool val) { drop_refs(); m_type = BOOLEAN; m_boolean_value = val; }		void	set_int(int val) { set_double(val); }		void	set_as_object_interface(as_object_interface* obj);		void	set_as_c_function_ptr(as_c_function_ptr func)		{			drop_refs(); m_type = C_FUNCTION; m_c_function_value = func;		}		void	set_as_as_function(as_as_function* func);		void	set_undefined() { drop_refs(); m_type = UNDEFINED; }		void	set_null() { drop_refs(); m_type = NULLTYPE; }		void	operator=(const as_value& v)		{			if (v.m_type == UNDEFINED) set_undefined();			else if (v.m_type == NULLTYPE) set_null();			else if (v.m_type == BOOLEAN) set_bool(v.m_boolean_value);			else if (v.m_type == STRING) set_tu_string(v.m_string_value);			else if (v.m_type == NUMBER) set_double(v.m_number_value);			else if (v.m_type == OBJECT) set_as_object_interface(v.m_object_value);			else if (v.m_type == C_FUNCTION) set_as_c_function_ptr(v.m_c_function_value);			else if (v.m_type == AS_FUNCTION) set_as_as_function(v.m_as_function_value);		}		bool	operator==(const as_value& v) const;		bool	operator!=(const as_value& v) const;		bool	operator<(const as_value& v) const { return to_number() < v.to_number(); }		void	operator+=(const as_value& v) { set_double(this->to_number() + v.to_number()); }		void	operator-=(const as_value& v) { set_double(this->to_number() - v.to_number()); }		void	operator*=(const as_value& v) { set_double(this->to_number() * v.to_number()); }		void	operator/=(const as_value& v) { set_double(this->to_number() / v.to_number()); }  // @@ check for div/0		void	operator&=(const as_value& v) { set_int(int(this->to_number()) & int(v.to_number())); }		void	operator|=(const as_value& v) { set_int(int(this->to_number()) | int(v.to_number())); }		void	operator^=(const as_value& v) { set_int(int(this->to_number()) ^ int(v.to_number())); }		void	shl(const as_value& v) { set_int(int(this->to_number()) << int(v.to_number())); }		void	asr(const as_value& v) { set_int(int(this->to_number()) >> int(v.to_number())); }		void	lsr(const as_value& v) { set_int((Uint32(this->to_number()) >> int(v.to_number()))); }		void	string_concat(const tu_string& str);		tu_string* get_mutable_tu_string() { assert(m_type == STRING); return &m_string_value; }	};// tulrich: I'm not too sure this is useful.  For things like// xml_as_object, is it sufficient to always store the event handlers// as ordinary members using their canonical names, instead of this// special table?  I have a feeling that's what Macromedia does// (though I'm not sure).#if 0	// This class is just as_object_interface, with an event	// handler table added.	struct as_object_with_handlers : public as_object_interface	{                // ActionScript event handler table.                hash<event_id, gameswf::as_value>        m_event_handlers;                // ActionScript event handler.                void    set_event_handler(event_id id, const as_value& method)                {                        // m_event_handlers.push_back(as);                        //m_event_handlers.set(id, method);                }                bool    get_event_handler(event_id id, gameswf::as_value* result)                {                        //return m_event_handlers.get(id, result);			return false;                }	};#endif // 0	//	// as_prop_flags	//	// flags defining the level of protection of a member	struct as_prop_flags	{		// Numeric flags		int m_flags;		// if true, this value is protected (internal to gameswf)		bool m_is_protected;		// mask for flags		const static int as_prop_flags_mask = 0x7;		// Default constructor		as_prop_flags() : m_flags(0), m_is_protected(false)		{		}		// Constructor		as_prop_flags(const bool read_only, const bool dont_delete, const bool dont_enum)			:			m_flags(((read_only) ? 0x4 : 0) | ((dont_delete) ? 0x2 : 0) | ((dont_enum) ? 0x1 : 0)),			m_is_protected(false)		{		}		// Constructor, from numerical value		as_prop_flags(const int flags)			: m_flags(flags), m_is_protected(false)		{		}		// accessor to m_readOnly		bool get_read_only() const { return (((this->m_flags & 0x4)!=0)?true:false); }		// accessor to m_dontDelete		bool get_dont_delete() const { return (((this->m_flags & 0x2)!=0)?true:false); }		// accessor to m_dontEnum		bool get_dont_enum() const { return (((this->m_flags & 0x1)!=0)?true:false);	}		// accesor to the numerical flags value		int get_flags() const { return this->m_flags; }		// accessor to m_is_protected

⌨️ 快捷键说明

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