📄 gameswf_action.h
字号:
bool get_is_protected() const { return this->m_is_protected; } // setter to m_is_protected void set_get_is_protected(const bool is_protected) { this->m_is_protected = is_protected; } // set the numerical flags value (return the new value ) // If unlocked is false, you cannot un-protect from over-write, // you cannot un-protect from deletion and you cannot // un-hide from the for..in loop construct int set_flags(const int setTrue, const int set_false = 0) { if (!this->get_is_protected()) { this->m_flags = this->m_flags & (~set_false); this->m_flags |= setTrue; } return get_flags(); } }; // // as_member // // member for as_object: value + flags struct as_member { // value as_value m_value; // Properties flags as_prop_flags m_flags; // Default constructor as_member() { } // Constructor as_member(const as_value &value,const as_prop_flags flags=as_prop_flags()) : m_value(value), m_flags(flags) { } // accessor to the value as_value get_member_value() const { return m_value; } // accessor to the properties flags as_prop_flags get_member_flags() const { return m_flags; } // set the value void set_member_value(const as_value &value) { m_value = value; } // accessor to the properties flags void set_member_flags(const as_prop_flags &flags) { m_flags = flags; } }; // // as_object // // A generic bag of attributes. Base-class for ActionScript // script-defined objects. struct as_object : public as_object_interface { stringi_hash<as_member> m_members; as_object_interface* m_prototype; as_object() : m_prototype(NULL) { } as_object(as_object_interface* proto) : m_prototype(proto) { if (m_prototype) { m_prototype->add_ref(); } } virtual ~as_object() { if (m_prototype) { m_prototype->drop_ref(); } } virtual const char* get_text_value() const { return NULL; } virtual void set_member(const tu_stringi& name, const as_value& val ) { //printf("SET MEMBER: %s at %p for object %p\n", name.c_str(), val.to_object(), this); if (name == "prototype") { if (m_prototype) m_prototype->drop_ref(); m_prototype = val.to_object(); if (m_prototype) m_prototype->add_ref(); } else { stringi_hash<as_member>::const_iterator it = this->m_members.find(name); if ( it != this->m_members.end() ) { const as_prop_flags flags = (it.get_value()).get_member_flags(); // is the member read-only ? if (!flags.get_read_only()) { m_members.set(name, as_member(val, flags)); } } else { m_members.set(name, as_member(val)); } } } virtual bool get_member(const tu_stringi& name, as_value* val) { //printf("GET MEMBER: %s at %p for object %p\n", name.c_str(), val, this); if (name == "prototype") { val->set_as_object_interface(m_prototype); return true; } else { as_member m; if (m_members.get(name, &m) == false) { if (m_prototype != NULL) { return m_prototype->get_member(name, val); } return false; } else { *val=m.get_member_value(); return true; } } return true; } virtual bool get_member(const tu_stringi& name, as_member* member) const { //printf("GET MEMBER: %s at %p for object %p\n", name.c_str(), val, this); assert(member != NULL); return m_members.get(name, member); } virtual bool set_member_flags(const tu_stringi& name, const int flags) { as_member member; if (this->get_member(name, &member)) { as_prop_flags f = member.get_member_flags(); f.set_flags(flags); member.set_member_flags(f); m_members.set(name, member); return true; } return false; } virtual movie* to_movie() // This object is not a movie; no conversion. { return NULL; } void clear() { m_members.clear(); if (m_prototype) { m_prototype->drop_ref(); m_prototype = NULL; } } }; // // as_as_function // // ActionScript function. struct as_as_function : public ref_counted { action_buffer* m_action_buffer; as_environment* m_env; // @@ might need some kind of ref count here, but beware cycles array<with_stack_entry> m_with_stack; // initial with-stack on function entry. int m_start_pc; int m_length; struct arg_spec { int m_register; tu_string m_name; }; array<arg_spec> m_args; bool m_is_function2; uint8 m_local_register_count; uint16 m_function2_flags; // used by function2 to control implicit arg register assignments // ActionScript functions have a property namespace! // Typically used for class constructors, for "prototype", "constructor", // and class properties. as_object* m_properties; // NULL environment is allowed -- if so, then // functions will be executed in the caller's // environment, rather than the environment where they // were defined. as_as_function(action_buffer* ab, as_environment* env, int start, const array<with_stack_entry>& with_stack) : m_action_buffer(ab), m_env(env), m_with_stack(with_stack), m_start_pc(start), m_length(0), m_is_function2(false), m_local_register_count(0), m_function2_flags(0), m_properties(NULL) { assert(m_action_buffer); } void set_is_function2() { m_is_function2 = true; } void set_local_register_count(uint8 ct) { assert(m_is_function2); m_local_register_count = ct; } void set_function2_flags(uint16 flags) { assert(m_is_function2); m_function2_flags = flags; } void add_arg(int arg_register, const char* name) { assert(arg_register == 0 || m_is_function2 == true); m_args.resize(m_args.size() + 1); m_args.back().m_register = arg_register; m_args.back().m_name = name; } void set_length(int len) { assert(len >= 0); m_length = len; } // Dispatch. void operator()(const fn_call& fn); void lazy_create_properties() // This ensures that this as_function has a valid // prototype in its properties. This is done lazily // so that functions/methods which are not used as // constructors don't carry along extra unnecessary // baggage. { if (m_properties == NULL) { m_properties = new as_object(); m_properties->add_ref(); // Create new empty prototype as_value proto(new as_object()); m_properties->set_member("prototype", proto); } } }; // ActionScript "environment", essentially VM state? struct as_environment { array<as_value> m_stack; as_value m_global_register[4]; array<as_value> m_local_register; // function2 uses this movie* m_target; stringi_hash<as_value> m_variables; // For local vars. Use empty names to separate frames. struct frame_slot { tu_string m_name; as_value m_value; frame_slot() {} frame_slot(const tu_string& name, const as_value& val) : m_name(name), m_value(val) {} }; array<frame_slot> m_local_frames; as_environment() : m_target(0) { } movie* get_target() { return m_target; } void set_target(movie* target) { m_target = target; } // stack access/manipulation // @@ TODO do more checking on these template<class T> void push(T val) { push_val(as_value(val)); } void push_val(const as_value& val) { m_stack.push_back(val); } as_value pop() { as_value result = m_stack.back(); m_stack.pop_back(); return result; } as_value& top(int dist) { return m_stack[m_stack.size() - 1 - dist]; } as_value& bottom(int index) { return m_stack[index]; } void drop(int count) { m_stack.resize(m_stack.size() - count); } int get_top_index() const { return m_stack.size() - 1; } as_value get_variable(const tu_string& varname, const array<with_stack_entry>& with_stack) const; // no path stuff: as_value get_variable_raw(const tu_string& varname, const array<with_stack_entry>& with_stack) const; void set_variable(const tu_string& path, const as_value& val, const array<with_stack_entry>& with_stack); // no path stuff: void set_variable_raw(const tu_string& path, const as_value& val, const array<with_stack_entry>& with_stack); void set_local(const tu_string& varname, const as_value& val); void add_local(const tu_string& varname, const as_value& val); // when you know it doesn't exist. void declare_local(const tu_string& varname); // Declare varname; undefined unless it already exists. bool get_member(const tu_stringi& varname, as_value* val) const; void set_member(const tu_stringi& varname, const as_value& val); // Parameter/local stack frame management. int get_local_frame_top() const { return m_local_frames.size(); } void set_local_frame_top(int t) { assert(t <= m_local_frames.size()); m_local_frames.resize(t); } void add_frame_barrier() { m_local_frames.push_back(frame_slot()); } // Local registers. void add_local_registers(int register_count) { m_local_register.resize(m_local_register.size() + register_count); } void drop_local_registers(int register_count) { m_local_register.resize(m_local_register.size() - register_count); } as_value* local_register_ptr(int reg); // Internal. int find_local(const tu_string& varname) const; bool parse_path(const tu_string& var_path, tu_string* path, tu_string* var) const; movie* find_target(const tu_string& path) const; movie* find_target(const as_value& val) const; }; // Parameters/environment for C functions callable from ActionScript. struct fn_call { as_value* result; as_object_interface* this_ptr; as_environment* env; int nargs; int first_arg_bottom_index; fn_call(as_value* res_in, as_object_interface* this_in, as_environment* env_in, int nargs_in, int first_in) : result(res_in), this_ptr(this_in), env(env_in), nargs(nargs_in), first_arg_bottom_index(first_in) { } as_value& arg(int n) const // Access a particular argument. { assert(n < nargs); return env->bottom(first_arg_bottom_index - n); } }; // // Some handy helpers // // Clean up any stray heap stuff we've allocated. void action_clear(); // Dispatching methods from C++. as_value call_method0(const as_value& method, as_environment* env, as_object_interface* this_ptr); as_value call_method1( const as_value& method, as_environment* env, as_object_interface* this_ptr, const as_value& arg0); as_value call_method2( const as_value& method, as_environment* env, as_object_interface* this_ptr, const as_value& arg0, const as_value& arg1); as_value call_method3( const as_value& method, as_environment* env, as_object_interface* this_ptr, const as_value& arg0, const as_value& arg1, const as_value& arg2); const char* call_method_parsed( as_environment* env, as_object_interface* this_ptr, const char* method_name, const char* method_arg_fmt, va_list args); // tulrich: don't use this! To register a class constructor, // just assign the classname to the constructor function. E.g.: // // my_movie->set_member("MyClass", as_value(MyClassConstructorFunction)); // //void register_as_object(const char* object_name, as_c_function_ptr handler); // Numerical indices for standard member names. Can use this // to help speed up get/set member calls, by using a switch() // instead of nasty string compares. enum as_standard_member { M_INVALID_MEMBER = -1, M_X, M_Y, M_XSCALE, M_YSCALE, M_CURRENTFRAME, M_TOTALFRAMES, M_ALPHA, M_VISIBLE, M_WIDTH, M_HEIGHT, M_ROTATION, M_TARGET, M_FRAMESLOADED, M_NAME, M_DROPTARGET, M_URL, M_HIGHQUALITY, M_FOCUSRECT, M_SOUNDBUFTIME, M_XMOUSE, M_YMOUSE, M_PARENT, M_TEXT, M_TEXTWIDTH, M_TEXTCOLOR, M_ONLOAD, AS_STANDARD_MEMBER_COUNT }; // Return the standard enum, if the arg names a standard member. // Returns M_INVALID_MEMBER if there's no match. as_standard_member get_standard_member(const tu_stringi& name);} // end namespace gameswf#endif // GAMESWF_ACTION_H// Local Variables:// mode: C++// c-basic-offset: 8 // tab-width: 8// indent-tabs-mode: t// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -