chore: Migrate from enumset to bitflags

This commit is contained in:
relrelb 2021-01-22 02:35:46 +02:00 committed by GitHub
parent 2254589e71
commit b05c6540e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
85 changed files with 1570 additions and 1387 deletions

585
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@ png = { version = "0.16.8" }
puremp3 = { version = "0.1", optional = true }
ruffle_macros = { path = "macros" }
swf = { path = "../swf" }
enumset = "1.0.1"
bitflags = "1.2.1"
smallvec = "1.6.1"
num_enum = "0.5.1"
quick-xml = "0.20.0"

View File

@ -22,7 +22,7 @@ mod fscommand;
pub mod function;
pub mod globals;
pub mod object;
mod property;
pub mod property;
mod scope;
mod string;
mod timer;

View File

@ -14,7 +14,6 @@ use crate::ecma_conversions::f64_to_wrapping_u32;
use crate::tag_utils::SwfSlice;
use crate::vminterface::Instantiator;
use crate::{avm_error, avm_warn};
use enumset::EnumSet;
use gc_arena::{Collect, Gc, GcCell, MutationContext};
use indexmap::IndexMap;
use rand::Rng;
@ -1146,16 +1145,16 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
sub_prototype.set_attributes(
self.context.gc_context,
Some("constructor"),
Attribute::DontEnum.into(),
EnumSet::empty(),
Attribute::DONT_ENUM,
Attribute::empty(),
);
sub_prototype.set("__constructor__", superclass.into(), self)?;
sub_prototype.set_attributes(
self.context.gc_context,
Some("__constructor__"),
Attribute::DontEnum.into(),
EnumSet::empty(),
Attribute::DONT_ENUM,
Attribute::empty(),
);
subclass.set("prototype", sub_prototype.into(), self)?;

View File

@ -3,13 +3,12 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::object::super_object::SuperObject;
use crate::avm1::property::{Attribute, Attribute::*};
use crate::avm1::property::Attribute;
use crate::avm1::scope::Scope;
use crate::avm1::value::Value;
use crate::avm1::{Object, ObjectPtr, ScriptObject, TObject};
use crate::display_object::{DisplayObject, TDisplayObject};
use crate::tag_utils::SwfSlice;
use enumset::EnumSet;
use gc_arena::{Collect, CollectionContext, Gc, GcCell, MutationContext};
use std::borrow::Cow;
use std::fmt;
@ -269,14 +268,14 @@ impl<'gc> Executable<'gc> {
activation.context.gc_context,
"callee",
callee.into(),
DontEnum.into(),
Attribute::DONT_ENUM,
);
// The caller is the previous callee.
arguments.define_value(
activation.context.gc_context,
"caller",
activation.callee.map(Value::from).unwrap_or(Value::Null),
DontEnum.into(),
Attribute::DONT_ENUM,
);
if !af.suppress_arguments {
@ -505,9 +504,9 @@ impl<'gc> FunctionObject<'gc> {
context,
"constructor",
Value::Object(function),
DontEnum.into(),
Attribute::DONT_ENUM,
);
function.define_value(context, "prototype", prototype.into(), EnumSet::empty());
function.define_value(context, "prototype", prototype.into(), Attribute::empty());
function
}
@ -594,16 +593,16 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
this.set_attributes(
activation.context.gc_context,
Some("__constructor__"),
Attribute::DontEnum.into(),
EnumSet::empty(),
Attribute::DONT_ENUM,
Attribute::empty(),
);
if activation.current_swf_version() < 7 {
this.set("constructor", (*self).into(), activation)?;
this.set_attributes(
activation.context.gc_context,
Some("constructor"),
Attribute::DontEnum.into(),
EnumSet::empty(),
Attribute::DONT_ENUM,
Attribute::empty(),
);
}
if let Some(exec) = &self.data.read().constructor {
@ -636,16 +635,16 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
this.set_attributes(
activation.context.gc_context,
Some("__constructor__"),
Attribute::DontEnum.into(),
EnumSet::empty(),
Attribute::DONT_ENUM,
Attribute::empty(),
);
if activation.current_swf_version() < 7 {
this.set("constructor", (*self).into(), activation)?;
this.set_attributes(
activation.context.gc_context,
Some("constructor"),
Attribute::DontEnum.into(),
EnumSet::empty(),
Attribute::DONT_ENUM,
Attribute::empty(),
);
}
if let Some(exec) = &self.data.read().constructor {
@ -715,7 +714,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
gc_context: MutationContext<'gc, '_>,
name: &str,
value: Value<'gc>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.base.define_value(gc_context, name, value, attributes)
}
@ -724,8 +723,8 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
&self,
gc_context: MutationContext<'gc, '_>,
name: Option<&str>,
set_attributes: EnumSet<Attribute>,
clear_attributes: EnumSet<Attribute>,
set_attributes: Attribute,
clear_attributes: Attribute,
) {
self.base
.set_attributes(gc_context, name, set_attributes, clear_attributes)
@ -737,7 +736,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
name: &str,
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.base
.add_property(gc_context, name, get, set, attributes)
@ -750,7 +749,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
name: &str,
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.base
.add_property_with_case(activation, gc_context, name, get, set, attributes)

View File

@ -1,9 +1,8 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::Collect;
use gc_arena::MutationContext;
use rand::Rng;
@ -701,19 +700,29 @@ pub fn create_globals<'gc>(
transform_proto,
);
flash.define_value(gc_context, "geom", geom.into(), EnumSet::empty());
flash.define_value(gc_context, "filters", filters.into(), EnumSet::empty());
flash.define_value(gc_context, "display", display.into(), EnumSet::empty());
geom.define_value(gc_context, "Matrix", matrix.into(), EnumSet::empty());
geom.define_value(gc_context, "Point", point.into(), EnumSet::empty());
geom.define_value(gc_context, "Rectangle", rectangle.into(), EnumSet::empty());
flash.define_value(gc_context, "geom", geom.into(), Attribute::empty());
flash.define_value(gc_context, "filters", filters.into(), Attribute::empty());
flash.define_value(gc_context, "display", display.into(), Attribute::empty());
geom.define_value(gc_context, "Matrix", matrix.into(), Attribute::empty());
geom.define_value(gc_context, "Point", point.into(), Attribute::empty());
geom.define_value(
gc_context,
"Rectangle",
rectangle.into(),
Attribute::empty(),
);
geom.define_value(
gc_context,
"ColorTransform",
color_transform.into(),
EnumSet::empty(),
Attribute::empty(),
);
geom.define_value(
gc_context,
"Transform",
transform.into(),
Attribute::empty(),
);
geom.define_value(gc_context, "Transform", transform.into(), EnumSet::empty());
let bitmap_filter_proto =
bitmap_filter::create_proto(gc_context, object_proto, Some(function_proto));
@ -819,62 +828,62 @@ pub fn create_globals<'gc>(
gc_context,
"BitmapFilter",
bitmap_filter.into(),
EnumSet::empty(),
Attribute::empty(),
);
filters.define_value(
gc_context,
"BlurFilter",
blur_filter.into(),
EnumSet::empty(),
Attribute::empty(),
);
filters.define_value(
gc_context,
"BevelFilter",
bevel_filter.into(),
EnumSet::empty(),
Attribute::empty(),
);
filters.define_value(
gc_context,
"GlowFilter",
glow_filter.into(),
EnumSet::empty(),
Attribute::empty(),
);
filters.define_value(
gc_context,
"DropShadowFilter",
drop_shadow_filter.into(),
EnumSet::empty(),
Attribute::empty(),
);
filters.define_value(
gc_context,
"ColorMatrixFilter",
color_matrix_filter.into(),
EnumSet::empty(),
Attribute::empty(),
);
filters.define_value(
gc_context,
"DisplacementMapFilter",
displacement_map_filter.into(),
EnumSet::empty(),
Attribute::empty(),
);
filters.define_value(
gc_context,
"ConvolutionFilter",
convolution_filter.into(),
EnumSet::empty(),
Attribute::empty(),
);
filters.define_value(
gc_context,
"GradientBevelFilter",
gradient_bevel_filter.into(),
EnumSet::empty(),
Attribute::empty(),
);
filters.define_value(
gc_context,
"GradientGlowFilter",
gradient_glow_filter.into(),
EnumSet::empty(),
Attribute::empty(),
);
let bitmap_data_proto = bitmap_data::create_proto(gc_context, object_proto, function_proto);
@ -885,7 +894,7 @@ pub fn create_globals<'gc>(
gc_context,
"BitmapData",
bitmap_data.into(),
EnumSet::empty(),
Attribute::empty(),
);
let external = ScriptObject::object(gc_context, Some(object_proto));
@ -895,12 +904,12 @@ pub fn create_globals<'gc>(
function_proto,
);
flash.define_value(gc_context, "external", external.into(), EnumSet::empty());
flash.define_value(gc_context, "external", external.into(), Attribute::empty());
external.define_value(
gc_context,
"ExternalInterface",
external_interface.into(),
EnumSet::empty(),
Attribute::empty(),
);
let mut globals = ScriptObject::bare_object(gc_context);
@ -908,37 +917,57 @@ pub fn create_globals<'gc>(
gc_context,
"AsBroadcaster",
as_broadcaster.into(),
DontEnum.into(),
Attribute::DONT_ENUM,
);
globals.define_value(gc_context, "flash", flash.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Array", array.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Button", button.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Color", color.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Error", error.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Object", object.into(), Attribute::DONT_ENUM);
globals.define_value(
gc_context,
"Function",
function.into(),
Attribute::DONT_ENUM,
);
globals.define_value(
gc_context,
"LoadVars",
load_vars.into(),
Attribute::DONT_ENUM,
);
globals.define_value(
gc_context,
"MovieClip",
movie_clip.into(),
Attribute::DONT_ENUM,
);
globals.define_value(gc_context, "flash", flash.into(), DontEnum.into());
globals.define_value(gc_context, "Array", array.into(), DontEnum.into());
globals.define_value(gc_context, "Button", button.into(), DontEnum.into());
globals.define_value(gc_context, "Color", color.into(), DontEnum.into());
globals.define_value(gc_context, "Error", error.into(), DontEnum.into());
globals.define_value(gc_context, "Object", object.into(), DontEnum.into());
globals.define_value(gc_context, "Function", function.into(), DontEnum.into());
globals.define_value(gc_context, "LoadVars", load_vars.into(), DontEnum.into());
globals.define_value(gc_context, "MovieClip", movie_clip.into(), DontEnum.into());
globals.define_value(
gc_context,
"MovieClipLoader",
movie_clip_loader.into(),
DontEnum.into(),
Attribute::DONT_ENUM,
);
globals.define_value(gc_context, "Sound", sound.into(), Attribute::DONT_ENUM);
globals.define_value(
gc_context,
"TextField",
text_field.into(),
Attribute::DONT_ENUM,
);
globals.define_value(gc_context, "Sound", sound.into(), DontEnum.into());
globals.define_value(gc_context, "TextField", text_field.into(), DontEnum.into());
globals.define_value(
gc_context,
"TextFormat",
text_format.into(),
DontEnum.into(),
Attribute::DONT_ENUM,
);
globals.define_value(gc_context, "XMLNode", xmlnode.into(), DontEnum.into());
globals.define_value(gc_context, "XML", xml.into(), DontEnum.into());
globals.define_value(gc_context, "String", string.into(), DontEnum.into());
globals.define_value(gc_context, "Number", number.into(), DontEnum.into());
globals.define_value(gc_context, "Boolean", boolean.into(), DontEnum.into());
globals.define_value(gc_context, "Date", date.into(), DontEnum.into());
globals.define_value(gc_context, "XMLNode", xmlnode.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "XML", xml.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "String", string.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Number", number.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Boolean", boolean.into(), Attribute::DONT_ENUM);
globals.define_value(gc_context, "Date", date.into(), Attribute::DONT_ENUM);
let shared_object_proto = shared_object::create_proto(gc_context, object_proto, function_proto);
@ -951,7 +980,7 @@ pub fn create_globals<'gc>(
gc_context,
"SharedObject",
shared_obj.into(),
DontEnum.into(),
Attribute::DONT_ENUM,
);
let context_menu = FunctionObject::constructor(
@ -965,7 +994,7 @@ pub fn create_globals<'gc>(
gc_context,
"ContextMenu",
context_menu.into(),
DontEnum.into(),
Attribute::DONT_ENUM,
);
let selection = selection::create_selection_object(
@ -975,7 +1004,12 @@ pub fn create_globals<'gc>(
broadcaster_functions,
array_proto,
);
globals.define_value(gc_context, "Selection", selection.into(), DontEnum.into());
globals.define_value(
gc_context,
"Selection",
selection.into(),
Attribute::DONT_ENUM,
);
let context_menu_item = FunctionObject::constructor(
gc_context,
@ -988,7 +1022,7 @@ pub fn create_globals<'gc>(
gc_context,
"ContextMenuItem",
context_menu_item.into(),
DontEnum.into(),
Attribute::DONT_ENUM,
);
let system_security = system_security::create(gc_context, Some(object_proto), function_proto);
@ -1010,7 +1044,7 @@ pub fn create_globals<'gc>(
system_capabilities,
system_ime,
);
globals.define_value(gc_context, "System", system.into(), DontEnum.into());
globals.define_value(gc_context, "System", system.into(), Attribute::DONT_ENUM);
globals.define_value(
gc_context,
@ -1020,7 +1054,7 @@ pub fn create_globals<'gc>(
Some(object_proto),
Some(function_proto),
)),
DontEnum.into(),
Attribute::DONT_ENUM,
);
globals.define_value(
gc_context,
@ -1032,7 +1066,7 @@ pub fn create_globals<'gc>(
broadcaster_functions,
array_proto,
)),
DontEnum.into(),
Attribute::DONT_ENUM,
);
globals.define_value(
gc_context,
@ -1044,7 +1078,7 @@ pub fn create_globals<'gc>(
broadcaster_functions,
array_proto,
)),
DontEnum.into(),
Attribute::DONT_ENUM,
);
globals.define_value(
gc_context,
@ -1056,72 +1090,90 @@ pub fn create_globals<'gc>(
function_proto,
broadcaster_functions,
)),
DontEnum.into(),
Attribute::DONT_ENUM,
);
globals.force_set_function(
"isFinite",
is_finite,
gc_context,
DontEnum,
Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function(
"isNaN",
is_nan,
gc_context,
Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function("isNaN", is_nan, gc_context, DontEnum, Some(function_proto));
globals.force_set_function(
"parseInt",
parse_int,
gc_context,
DontEnum,
Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function(
"parseFloat",
parse_float,
gc_context,
DontEnum,
Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function(
"random",
random,
gc_context,
Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function("random", random, gc_context, DontEnum, Some(function_proto));
globals.force_set_function(
"ASSetPropFlags",
object::as_set_prop_flags,
gc_context,
DontEnum,
Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function(
"clearInterval",
clear_interval,
gc_context,
DontEnum,
Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function(
"setInterval",
set_interval,
gc_context,
DontEnum,
Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function(
"setTimeout",
set_timeout,
gc_context,
DontEnum,
Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function(
"updateAfterEvent",
update_after_event,
gc_context,
DontEnum,
Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function(
"escape",
escape,
gc_context,
Attribute::DONT_ENUM,
Some(function_proto),
);
globals.force_set_function("escape", escape, gc_context, DontEnum, Some(function_proto));
globals.force_set_function(
"unescape",
unescape,
gc_context,
DontEnum,
Attribute::DONT_ENUM,
Some(function_proto),
);
@ -1135,7 +1187,7 @@ pub fn create_globals<'gc>(
function_proto,
),
None,
DontEnum.into(),
Attribute::DONT_ENUM,
);
globals.add_property(
gc_context,
@ -1147,7 +1199,7 @@ pub fn create_globals<'gc>(
function_proto,
),
None,
DontEnum.into(),
Attribute::DONT_ENUM,
);
(

View File

@ -46,35 +46,35 @@ pub fn create_array_object<'gc>(
gc_context,
"CASEINSENSITIVE",
1.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_ENUM | Attribute::DONT_DELETE | Attribute::READ_ONLY,
);
object.define_value(
gc_context,
"DESCENDING",
2.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_ENUM | Attribute::DONT_DELETE | Attribute::READ_ONLY,
);
object.define_value(
gc_context,
"UNIQUESORT",
4.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_ENUM | Attribute::DONT_DELETE | Attribute::READ_ONLY,
);
object.define_value(
gc_context,
"RETURNINDEXEDARRAY",
8.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_ENUM | Attribute::DONT_DELETE | Attribute::READ_ONLY,
);
object.define_value(
gc_context,
"NUMERIC",
16.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_ENUM | Attribute::DONT_DELETE | Attribute::READ_ONLY,
);
array
@ -663,78 +663,78 @@ pub fn create_proto<'gc>(
"push",
push,
gc_context,
Attribute::DontEnum,
Attribute::DONT_ENUM,
Some(fn_proto),
);
object.force_set_function(
"unshift",
unshift,
gc_context,
Attribute::DontEnum,
Attribute::DONT_ENUM,
Some(fn_proto),
);
object.force_set_function(
"shift",
shift,
gc_context,
Attribute::DontEnum,
Attribute::DONT_ENUM,
Some(fn_proto),
);
object.force_set_function("pop", pop, gc_context, Attribute::DontEnum, Some(fn_proto));
object.force_set_function("pop", pop, gc_context, Attribute::DONT_ENUM, Some(fn_proto));
object.force_set_function(
"reverse",
reverse,
gc_context,
Attribute::DontEnum,
Attribute::DONT_ENUM,
Some(fn_proto),
);
object.force_set_function(
"join",
join,
gc_context,
Attribute::DontEnum,
Attribute::DONT_ENUM,
Some(fn_proto),
);
object.force_set_function(
"slice",
slice,
gc_context,
Attribute::DontEnum,
Attribute::DONT_ENUM,
Some(fn_proto),
);
object.force_set_function(
"splice",
splice,
gc_context,
Attribute::DontEnum,
Attribute::DONT_ENUM,
Some(fn_proto),
);
object.force_set_function(
"concat",
concat,
gc_context,
Attribute::DontEnum,
Attribute::DONT_ENUM,
Some(fn_proto),
);
object.force_set_function(
"toString",
to_string,
gc_context,
Attribute::DontEnum,
Attribute::DONT_ENUM,
Some(fn_proto),
);
object.force_set_function(
"sort",
sort,
gc_context,
Attribute::DontEnum,
Attribute::DONT_ENUM,
Some(fn_proto),
);
object.force_set_function(
"sortOn",
sort_on,
gc_context,
Attribute::DontEnum,
Attribute::DONT_ENUM,
Some(fn_proto),
);

View File

@ -4,7 +4,7 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::TObject;
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, Value};
use gc_arena::{Collect, MutationContext};
@ -165,27 +165,32 @@ pub fn initialize_internal<'gc>(
) {
let listeners = ScriptObject::array(gc_context, Some(array_proto));
broadcaster.define_value(gc_context, "_listeners", listeners.into(), DontEnum.into());
broadcaster.define_value(
gc_context,
"_listeners",
listeners.into(),
Attribute::DONT_ENUM,
);
broadcaster.define_value(
gc_context,
"addListener",
functions.add_listener.into(),
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
broadcaster.define_value(
gc_context,
"removeListener",
functions.remove_listener.into(),
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
broadcaster.define_value(
gc_context,
"broadcastMessage",
functions.broadcast_message.into(),
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
}
@ -200,7 +205,7 @@ pub fn create<'gc>(
"initialize",
initialize,
gc_context,
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -214,7 +219,7 @@ pub fn create<'gc>(
gc_context,
"addListener",
add_listener.into(),
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
let remove_listener = FunctionObject::function(
@ -227,7 +232,7 @@ pub fn create<'gc>(
gc_context,
"removeListener",
remove_listener.into(),
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
let broadcast_message = FunctionObject::function(
@ -240,7 +245,7 @@ pub fn create<'gc>(
gc_context,
"broadcastMessage",
broadcast_message.into(),
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
(

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::bevel_filter::{BevelFilterObject, BevelFilterType};
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -417,7 +417,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
script_object.add_property(
gc_context,
@ -434,7 +434,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
script_object.add_property(
gc_context,
@ -451,7 +451,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
script_object.add_property(
gc_context,
@ -468,7 +468,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
script_object.add_property(
gc_context,
@ -485,7 +485,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
script_object.add_property(
gc_context,
@ -502,7 +502,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
script_object.add_property(
gc_context,
@ -519,7 +519,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
script_object.add_property(
gc_context,
@ -536,7 +536,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
script_object.add_property(
gc_context,
@ -553,7 +553,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
script_object.add_property(
gc_context,
@ -570,7 +570,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
script_object.add_property(
gc_context,
@ -587,7 +587,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
script_object.add_property(
gc_context,
@ -604,7 +604,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.into()
}

View File

@ -3,11 +3,11 @@
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::bitmap_data::{BitmapDataObject, ChannelOptions, Color};
use crate::avm1::property::Attribute;
use crate::avm1::{activation::Activation, object::bitmap_data::BitmapData};
use crate::avm1::{Object, TObject, Value};
use crate::character::Character;
use crate::display_object::TDisplayObject;
use enumset::EnumSet;
use gc_arena::{GcCell, MutationContext};
pub fn constructor<'gc>(
@ -847,7 +847,7 @@ pub fn create_proto<'gc>(
fn_proto,
),
None,
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -860,7 +860,7 @@ pub fn create_proto<'gc>(
fn_proto,
),
None,
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -873,7 +873,7 @@ pub fn create_proto<'gc>(
fn_proto,
),
None,
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -886,144 +886,162 @@ pub fn create_proto<'gc>(
fn_proto,
),
None,
EnumSet::empty(),
Attribute::empty(),
);
object.force_set_function(
"getPixel",
get_pixel,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"getPixel32",
get_pixel32,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"setPixel",
set_pixel,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"setPixel32",
set_pixel32,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"copyChannel",
copy_channel,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"fillRect",
fill_rect,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"clone",
clone,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("clone", clone, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function(
"dispose",
dispose,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"floodFill",
flood_fill,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"noise",
noise,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("noise", noise, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function(
"colorTransform",
color_transform,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"getColorBoundsRect",
get_color_bounds_rect,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"perlinNoise",
perlin_noise,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"applyFilter",
apply_filter,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("draw", draw, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function("draw", draw, gc_context, Attribute::empty(), Some(fn_proto));
object.force_set_function(
"hitTest",
hit_test,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"generateFilterRect",
generate_filter_rect,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"copyPixels",
copy_pixels,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"merge",
merge,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("merge", merge, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function(
"paletteMap",
palette_map,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"pixelDissolve",
pixel_dissolve,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"scroll",
scroll,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"threshold",
threshold,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -1092,7 +1110,7 @@ pub fn create_bitmap_data_object<'gc>(
"loadBitmap",
load_bitmap,
gc_context,
EnumSet::empty(),
Attribute::empty(),
fn_proto,
);

View File

@ -2,8 +2,8 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -275,7 +275,7 @@ pub fn create_proto<'gc>(
) -> Object<'gc> {
let mut object = ScriptObject::object(gc_context, Some(proto));
object.force_set_function("clone", clone, gc_context, EnumSet::empty(), fn_proto);
object.force_set_function("clone", clone, gc_context, Attribute::empty(), fn_proto);
object.into()
}

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::blur_filter::BlurFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -133,7 +133,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -151,7 +151,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -169,7 +169,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
blur_filter.into()

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::value_object::ValueObject;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
/// `Boolean` constructor
@ -72,14 +72,14 @@ pub fn create_proto<'gc>(
"toString",
to_string,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"valueOf",
value_of,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);

View File

@ -4,7 +4,7 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::display_object;
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value};
use crate::display_object::{Button, TDisplayObject};
use gc_arena::MutationContext;
@ -17,7 +17,7 @@ macro_rules! with_button_props {
$name,
with_button_props!(getter $gc, $fn_proto, $get),
with_button_props!(setter $gc, $fn_proto, $($set),*),
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
)*
};

View File

@ -5,10 +5,9 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value};
use crate::display_object::{DisplayObject, TDisplayObject};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -23,8 +22,8 @@ pub fn constructor<'gc>(
this.set_attributes(
activation.context.gc_context,
Some("target"),
DontDelete | ReadOnly | DontEnum,
EnumSet::empty(),
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Attribute::empty(),
);
Ok(this.into())
@ -41,7 +40,7 @@ pub fn create_proto<'gc>(
"getRGB",
get_rgb,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -49,7 +48,7 @@ pub fn create_proto<'gc>(
"getTransform",
get_transform,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -57,7 +56,7 @@ pub fn create_proto<'gc>(
"setRGB",
set_rgb,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -65,7 +64,7 @@ pub fn create_proto<'gc>(
"setTransform",
set_transform,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::color_matrix_filter::ColorMatrixFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -88,7 +88,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
color_matrix_filter.into()

View File

@ -3,8 +3,8 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
use crate::avm1::object::color_transform_object::ColorTransformObject;
@ -19,7 +19,7 @@ macro_rules! with_color_transform {
$name,
FunctionObject::function($gc, Executable::Native($get), Some($fn_proto), $fn_proto),
Some(FunctionObject::function($gc, Executable::Native($set), Some($fn_proto), $fn_proto)),
EnumSet::empty(),
Attribute::empty(),
);
)*
}
@ -260,7 +260,7 @@ pub fn create_proto<'gc>(
"concat",
concat,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -268,7 +268,7 @@ pub fn create_proto<'gc>(
"toString",
to_string,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);

View File

@ -143,7 +143,7 @@ pub fn create_proto<'gc>(
"copy",
copy,
gc_context,
Attribute::DontEnum | Attribute::DontDelete,
Attribute::DONT_ENUM | Attribute::DONT_DELETE,
Some(fn_proto),
);
@ -151,7 +151,7 @@ pub fn create_proto<'gc>(
"hideBuiltInItems",
hide_builtin_items,
gc_context,
Attribute::DontEnum | Attribute::DontDelete,
Attribute::DONT_ENUM | Attribute::DONT_DELETE,
Some(fn_proto),
);

View File

@ -108,7 +108,7 @@ pub fn create_proto<'gc>(
"copy",
copy,
gc_context,
Attribute::DontEnum | Attribute::DontDelete,
Attribute::DONT_ENUM | Attribute::DONT_DELETE,
Some(fn_proto),
);

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::convolution_filter::ConvolutionFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -337,7 +337,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -355,7 +355,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -373,7 +373,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -391,7 +391,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -409,7 +409,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -427,7 +427,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -445,7 +445,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -463,7 +463,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -481,7 +481,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
filter.into()

View File

@ -5,7 +5,6 @@ use crate::avm1::object::date_object::DateObject;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value};
use chrono::{DateTime, Datelike, Duration, FixedOffset, LocalResult, TimeZone, Timelike, Utc};
use enumset::EnumSet;
use gc_arena::{Collect, MutationContext};
use num_traits::ToPrimitive;
use std::f64::NAN;
@ -28,7 +27,7 @@ macro_rules! implement_local_getters {
}
} as crate::avm1::function::NativeFunction<'gc>,
$gc_context,
Attribute::DontDelete | Attribute::ReadOnly | Attribute::DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$fn_proto
);
)*
@ -48,7 +47,7 @@ macro_rules! implement_methods {
}
} as crate::avm1::function::NativeFunction<'gc>,
$gc_context,
Attribute::DontDelete | Attribute::ReadOnly | Attribute::DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$fn_proto
);
)*
@ -72,7 +71,7 @@ macro_rules! implement_utc_getters {
}
} as crate::avm1::function::NativeFunction<'gc>,
$gc_context,
Attribute::DontDelete | Attribute::ReadOnly | Attribute::DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$fn_proto
);
)*
@ -906,7 +905,7 @@ pub fn create_date_object<'gc>(
);
let mut object = date.as_script_object().unwrap();
object.force_set_function("UTC", create_utc, gc_context, EnumSet::empty(), fn_proto);
object.force_set_function("UTC", create_utc, gc_context, Attribute::empty(), fn_proto);
date
}

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::displacement_map_filter::DisplacementMapFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -328,7 +328,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -346,7 +346,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -364,7 +364,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -382,7 +382,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -400,7 +400,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -418,7 +418,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -436,7 +436,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -454,7 +454,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -472,7 +472,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
filter.into()

View File

@ -3,10 +3,9 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use crate::display_object::{DisplayObject, TDisplayObject, TDisplayObjectContainer};
use enumset::EnumSet;
use crate::display_object::{DisplayObject, Lists, TDisplayObject, TDisplayObjectContainer};
use gc_arena::MutationContext;
/// Depths used/returned by ActionScript are offset by this amount from depths used inside the SWF/by the VM.
@ -35,7 +34,7 @@ macro_rules! with_display_object {
Ok(Value::Undefined)
} as crate::avm1::function::NativeFunction<'gc>,
$gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$fn_proto
);
)*
@ -73,7 +72,7 @@ pub fn define_display_object_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
object.add_property(
@ -91,7 +90,7 @@ pub fn define_display_object_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
object.add_property(
@ -109,7 +108,7 @@ pub fn define_display_object_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
}
@ -160,7 +159,7 @@ pub fn overwrite_root<'gc>(
activation.context.gc_context,
"_root",
new_val,
EnumSet::new(),
Attribute::empty(),
);
Ok(Value::Undefined)
@ -179,7 +178,7 @@ pub fn overwrite_global<'gc>(
activation.context.gc_context,
"_global",
new_val,
EnumSet::new(),
Attribute::empty(),
);
Ok(Value::Undefined)
@ -198,7 +197,7 @@ pub fn overwrite_parent<'gc>(
activation.context.gc_context,
"_parent",
new_val,
EnumSet::new(),
Attribute::empty(),
);
Ok(Value::Undefined)
@ -216,7 +215,7 @@ pub fn remove_display_object<'gc>(
if depth >= AVM_DEPTH_BIAS && depth < AVM_MAX_REMOVE_DEPTH && !this.removed() {
// Need a parent to remove from.
if let Some(mut parent) = this.parent().and_then(|o| o.as_movie_clip()) {
parent.remove_child(&mut activation.context, this, EnumSet::all());
parent.remove_child(&mut activation.context, this, Lists::all());
}
}
}

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::drop_shadow_filter::DropShadowFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -381,7 +381,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -399,7 +399,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -417,7 +417,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -435,7 +435,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -453,7 +453,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -471,7 +471,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -489,7 +489,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -507,7 +507,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -525,7 +525,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -543,7 +543,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -561,7 +561,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
drop_shadow_filter.into()

View File

@ -2,9 +2,8 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -29,14 +28,14 @@ pub fn create_proto<'gc>(
) -> Object<'gc> {
let mut object = ScriptObject::object(gc_context, Some(proto));
object.define_value(gc_context, "message", "Error".into(), EnumSet::empty());
object.define_value(gc_context, "name", "Error".into(), EnumSet::empty());
object.define_value(gc_context, "message", "Error".into(), Attribute::empty());
object.define_value(gc_context, "name", "Error".into(), Attribute::empty());
object.force_set_function(
"toString",
to_string,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);

View File

@ -81,14 +81,14 @@ pub fn create_external_interface_object<'gc>(
fn_proto,
),
None,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
object.force_set_function(
"addCallback",
add_callback,
gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -96,7 +96,7 @@ pub fn create_external_interface_object<'gc>(
"call",
call,
gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);

View File

@ -3,8 +3,8 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::ExecutionReason;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
/// Implements `new Function()`
@ -121,15 +121,15 @@ pub fn create_proto<'gc>(gc_context: MutationContext<'gc, '_>, proto: Object<'gc
function_proto
.as_script_object()
.unwrap()
.force_set_function("call", call, gc_context, EnumSet::empty(), this);
.force_set_function("call", call, gc_context, Attribute::empty(), this);
function_proto
.as_script_object()
.unwrap()
.force_set_function("apply", apply, gc_context, EnumSet::empty(), this);
.force_set_function("apply", apply, gc_context, Attribute::empty(), this);
function_proto
.as_script_object()
.unwrap()
.force_set_function("toString", to_string, gc_context, EnumSet::empty(), this);
.force_set_function("toString", to_string, gc_context, Attribute::empty(), this);
function_proto
}

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::glow_filter::GlowFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -284,7 +284,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -302,7 +302,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -320,7 +320,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -338,7 +338,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -356,7 +356,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -374,7 +374,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -392,7 +392,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -410,7 +410,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
glow_filter.into()

View File

@ -5,8 +5,8 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::bevel_filter::BevelFilterType;
use crate::avm1::object::gradient_bevel_filter::GradientBevelFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -477,7 +477,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -495,7 +495,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -513,7 +513,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -531,7 +531,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -549,7 +549,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -567,7 +567,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -585,7 +585,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -603,7 +603,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -621,7 +621,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -639,7 +639,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -657,7 +657,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
color_matrix_filter.into()

View File

@ -5,8 +5,8 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::bevel_filter::BevelFilterType;
use crate::avm1::object::gradient_glow_filter::GradientGlowFilterObject;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -477,7 +477,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -495,7 +495,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -513,7 +513,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -531,7 +531,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -549,7 +549,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -567,7 +567,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -585,7 +585,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -603,7 +603,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -621,7 +621,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -639,7 +639,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
object.add_property(
@ -657,7 +657,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
color_matrix_filter.into()

View File

@ -56,122 +56,122 @@ pub fn create_key_object<'gc>(
gc_context,
"ALT",
18.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"BACKSPACE",
8.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"CAPSLOCK",
20.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"CONTROL",
17.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"DELETEKEY",
46.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"DOWN",
40.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"END",
35.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"ENTER",
13.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"ESCAPE",
27.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"HOME",
36.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"INSERT",
45.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"LEFT",
37.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"PGDN",
34.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"PGUP",
33.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"RIGHT",
39.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"SHIFT",
16.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"SPACE",
32.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"TAB",
9.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.define_value(
gc_context,
"UP",
38.into(),
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
key.force_set_function(
"isDown",
is_down,
gc_context,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
@ -179,7 +179,7 @@ pub fn create_key_object<'gc>(
"getAscii",
get_ascii,
gc_context,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
@ -187,7 +187,7 @@ pub fn create_key_object<'gc>(
"getCode",
get_code,
gc_context,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);

View File

@ -25,15 +25,13 @@ pub fn create_proto<'gc>(
proto: Object<'gc>,
fn_proto: Object<'gc>,
) -> Object<'gc> {
use Attribute::*;
let mut object = ScriptObject::object(gc_context, Some(proto));
object.force_set_function(
"load",
load,
gc_context,
DontDelete | DontEnum | ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -41,7 +39,7 @@ pub fn create_proto<'gc>(
"send",
send,
gc_context,
DontDelete | DontEnum | ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -49,7 +47,7 @@ pub fn create_proto<'gc>(
"sendAndLoad",
send_and_load,
gc_context,
DontDelete | DontEnum | ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -57,7 +55,7 @@ pub fn create_proto<'gc>(
"decode",
decode,
gc_context,
DontDelete | DontEnum | ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -65,7 +63,7 @@ pub fn create_proto<'gc>(
"getBytesLoaded",
get_bytes_loaded,
gc_context,
DontDelete | DontEnum | ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -73,7 +71,7 @@ pub fn create_proto<'gc>(
"getBytesTotal",
get_bytes_total,
gc_context,
DontDelete | DontEnum | ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -81,7 +79,7 @@ pub fn create_proto<'gc>(
"toString",
to_string,
gc_context,
DontDelete | DontEnum | ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -89,14 +87,14 @@ pub fn create_proto<'gc>(
gc_context,
"contentType",
"application/x-www-form-url-encoded".into(),
DontDelete | DontEnum | ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
object.force_set_function(
"onLoad",
on_load,
gc_context,
DontDelete | DontEnum | ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -104,7 +102,7 @@ pub fn create_proto<'gc>(
"onData",
on_data,
gc_context,
DontDelete | DontEnum | ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -112,7 +110,7 @@ pub fn create_proto<'gc>(
"addRequestHeader",
add_request_header,
gc_context,
DontDelete | DontEnum | ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -343,7 +341,7 @@ fn spawn_load_var_fetch<'gc>(
activation.context.gc_context,
"_bytesLoaded",
0.into(),
Attribute::DontDelete | Attribute::DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
} else {
loader_object.set("_bytesLoaded", 0.into(), activation)?;
@ -354,7 +352,7 @@ fn spawn_load_var_fetch<'gc>(
activation.context.gc_context,
"loaded",
false.into(),
Attribute::DontDelete | Attribute::DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
} else {
loader_object.set("loaded", false.into(), activation)?;

View File

@ -1,7 +1,7 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::object::Object;
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{ScriptObject, TObject, Value};
use gc_arena::MutationContext;
use rand::Rng;
@ -20,7 +20,7 @@ macro_rules! wrap_std {
}
},
$gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$proto
);
)*
@ -144,49 +144,49 @@ pub fn create<'gc>(
gc_context,
"E",
std::f64::consts::E.into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
math.define_value(
gc_context,
"LN10",
std::f64::consts::LN_10.into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
math.define_value(
gc_context,
"LN2",
std::f64::consts::LN_2.into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
math.define_value(
gc_context,
"LOG10E",
std::f64::consts::LOG10_E.into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
math.define_value(
gc_context,
"LOG2E",
std::f64::consts::LOG2_E.into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
math.define_value(
gc_context,
"PI",
std::f64::consts::PI.into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
math.define_value(
gc_context,
"SQRT1_2",
std::f64::consts::FRAC_1_SQRT_2.into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
math.define_value(
gc_context,
"SQRT2",
std::f64::consts::SQRT_2.into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
wrap_std!(math, gc_context, fn_proto,
@ -208,42 +208,42 @@ pub fn create<'gc>(
"atan2",
atan2,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
math.force_set_function(
"pow",
pow,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
math.force_set_function(
"max",
max,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
math.force_set_function(
"min",
min,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
math.force_set_function(
"random",
random,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
math.force_set_function(
"round",
round,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);

View File

@ -4,8 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::point::{point_to_object, value_to_point};
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
use swf::{Matrix, Twips};
@ -427,7 +427,7 @@ pub fn create_proto<'gc>(
"toString",
to_string,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -435,19 +435,31 @@ pub fn create_proto<'gc>(
"identity",
identity,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("clone", clone, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function(
"clone",
clone,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("scale", scale, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function(
"scale",
scale,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"rotate",
rotate,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -455,7 +467,7 @@ pub fn create_proto<'gc>(
"translate",
translate,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -463,7 +475,7 @@ pub fn create_proto<'gc>(
"concat",
concat,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -471,7 +483,7 @@ pub fn create_proto<'gc>(
"invert",
invert,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -479,7 +491,7 @@ pub fn create_proto<'gc>(
"createBox",
create_box,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -487,7 +499,7 @@ pub fn create_proto<'gc>(
"createGradientBox",
create_gradient_box,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -495,7 +507,7 @@ pub fn create_proto<'gc>(
"transformPoint",
transform_point,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -503,7 +515,7 @@ pub fn create_proto<'gc>(
"deltaTransformPoint",
delta_transform_point,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);

View File

@ -48,7 +48,7 @@ pub fn create_mouse_object<'gc>(
"show",
show_mouse,
gc_context,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
@ -56,7 +56,7 @@ pub fn create_mouse_object<'gc>(
"hide",
hide_mouse,
gc_context,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);

View File

@ -5,7 +5,7 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::display_object::{self, AVM_DEPTH_BIAS, AVM_MAX_DEPTH};
use crate::avm1::globals::matrix::gradient_object_to_matrix;
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use crate::avm_error;
use crate::avm_warn;
@ -48,7 +48,7 @@ macro_rules! with_movie_clip {
Ok(Value::Undefined)
} as crate::avm1::function::NativeFunction<'gc>,
$gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$fn_proto
);
)*
@ -63,7 +63,7 @@ macro_rules! with_movie_clip_props {
$name,
with_movie_clip_props!(getter $gc, $fn_proto, $get),
with_movie_clip_props!(setter $gc, $fn_proto, $($set),*),
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
)*
};
@ -209,7 +209,7 @@ pub fn create_proto<'gc>(
"removeMovieClip",
remove_movie_clip,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);

View File

@ -9,7 +9,6 @@ use crate::avm1::property::Attribute;
use crate::avm1::{Object, Value};
use crate::backend::navigator::RequestOptions;
use crate::display_object::{DisplayObject, TDisplayObject};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
@ -25,7 +24,7 @@ pub fn constructor<'gc>(
activation.context.gc_context,
"_listeners",
Value::Object(listeners.into()),
Attribute::DontEnum.into(),
Attribute::DONT_ENUM,
);
listeners.set_array_element(0, Value::Object(this), activation.context.gc_context);
@ -109,7 +108,7 @@ pub fn get_progress<'gc>(
.movie()
.map(|mv| (mv.header().uncompressed_length).into())
.unwrap_or(Value::Undefined),
EnumSet::empty(),
Attribute::empty(),
);
ret_obj.define_value(
activation.context.gc_context,
@ -118,7 +117,7 @@ pub fn get_progress<'gc>(
.movie()
.map(|mv| (mv.header().uncompressed_length).into())
.unwrap_or(Value::Undefined),
EnumSet::empty(),
Attribute::empty(),
);
return Ok(ret_obj.into());
@ -143,21 +142,21 @@ pub fn create_proto<'gc>(
"loadClip",
load_clip,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
mcl_proto.as_script_object().unwrap().force_set_function(
"unloadClip",
unload_clip,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
mcl_proto.as_script_object().unwrap().force_set_function(
"getProgress",
get_progress,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);

View File

@ -4,9 +4,8 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::value_object::ValueObject;
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
/// `Number` constructor
@ -63,7 +62,7 @@ pub fn create_number_object<'gc>(
gc_context,
"MAX_VALUE",
std::f64::MAX.into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
object.define_value(
@ -72,28 +71,28 @@ pub fn create_number_object<'gc>(
// Note this is actually the smallest positive denormalized f64.
// Rust doesn't provide a constant for this (`MIN_POSITIVE` is a normal f64).
Value::Number(f64::from_bits(1)),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
object.define_value(
gc_context,
"NaN",
std::f64::NAN.into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
object.define_value(
gc_context,
"NEGATIVE_INFINITY",
std::f64::NEG_INFINITY.into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
object.define_value(
gc_context,
"POSITIVE_INFINITY",
std::f64::INFINITY.into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
number
@ -112,14 +111,14 @@ pub fn create_proto<'gc>(
"toString",
to_string,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"valueOf",
value_of,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);

View File

@ -2,11 +2,10 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute::{self, *};
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value};
use crate::avm_warn;
use crate::display_object::TDisplayObject;
use enumset::EnumSet;
use gc_arena::MutationContext;
use std::borrow::Cow;
@ -60,7 +59,7 @@ pub fn add_property<'gc>(
&name,
get.to_owned(),
Some(set.to_owned()),
EnumSet::empty(),
Attribute::empty(),
);
} else if let Value::Null = setter {
this.add_property_with_case(
@ -69,7 +68,7 @@ pub fn add_property<'gc>(
&name,
get.to_owned(),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
} else {
return Ok(false.into());
@ -248,56 +247,56 @@ pub fn fill_proto<'gc>(
"addProperty",
add_property,
gc_context,
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto),
);
object_proto.as_script_object().unwrap().force_set_function(
"hasOwnProperty",
has_own_property,
gc_context,
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto),
);
object_proto.as_script_object().unwrap().force_set_function(
"isPropertyEnumerable",
is_property_enumerable,
gc_context,
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto),
);
object_proto.as_script_object().unwrap().force_set_function(
"isPrototypeOf",
is_prototype_of,
gc_context,
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto),
);
object_proto.as_script_object().unwrap().force_set_function(
"toString",
to_string,
gc_context,
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto),
);
object_proto.as_script_object().unwrap().force_set_function(
"valueOf",
value_of,
gc_context,
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto),
);
object_proto.as_script_object().unwrap().force_set_function(
"watch",
watch,
gc_context,
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto),
);
object_proto.as_script_object().unwrap().force_set_function(
"unwatch",
unwatch,
gc_context,
DontDelete | DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
Some(fn_proto),
);
}
@ -349,22 +348,22 @@ pub fn as_set_prop_flags<'gc>(
let set_flags = args
.get(2)
.unwrap_or(&Value::Number(0.0))
.coerce_to_f64(activation)? as u128;
let clear_flags = args
.get(2)
.unwrap_or(&Value::Number(0.0))
.coerce_to_f64(activation)? as u128;
.coerce_to_f64(activation)? as u8;
let set_attributes = Attribute::from_bits_truncate(set_flags);
if set_flags > 0b111 || clear_flags > 0b111 {
let clear_flags = args
.get(3)
.unwrap_or(&Value::Number(0.0))
.coerce_to_f64(activation)? as u8;
let clear_attributes = Attribute::from_bits_truncate(clear_flags);
if set_attributes.bits() != set_flags || clear_attributes.bits() != clear_flags {
avm_warn!(
activation,
"ASSetPropFlags: Unimplemented support for flags > 7"
);
}
let set_attributes = EnumSet::<Attribute>::from_u128(set_flags & 0b111);
let clear_attributes = EnumSet::<Attribute>::from_u128(clear_flags & 0b111);
match properties {
Some(properties) => {
for prop_name in properties {
@ -405,7 +404,7 @@ pub fn create_object_object<'gc>(
"registerClass",
register_class,
gc_context,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);

View File

@ -5,7 +5,6 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
use std::f64::NAN;
@ -276,13 +275,19 @@ pub fn create_point_object<'gc>(
);
let mut object = point.as_script_object().unwrap();
object.force_set_function("distance", distance, gc_context, EnumSet::empty(), fn_proto);
object.force_set_function("polar", polar, gc_context, EnumSet::empty(), fn_proto);
object.force_set_function(
"distance",
distance,
gc_context,
Attribute::empty(),
fn_proto,
);
object.force_set_function("polar", polar, gc_context, Attribute::empty(), fn_proto);
object.force_set_function(
"interpolate",
interpolate,
gc_context,
EnumSet::empty(),
Attribute::empty(),
fn_proto,
);
@ -300,27 +305,33 @@ pub fn create_proto<'gc>(
"toString",
to_string,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("clone", clone, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function(
"clone",
clone,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"equals",
equals,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("add", add, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function("add", add, gc_context, Attribute::empty(), Some(fn_proto));
object.force_set_function(
"subtract",
subtract,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -328,7 +339,7 @@ pub fn create_proto<'gc>(
"normalize",
normalize,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -336,7 +347,7 @@ pub fn create_proto<'gc>(
"offset",
offset,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -350,7 +361,7 @@ pub fn create_proto<'gc>(
fn_proto,
),
None,
Attribute::ReadOnly.into(),
Attribute::READ_ONLY,
);
object.into()

View File

@ -6,7 +6,6 @@ use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::point::{construct_new_point, point_to_object, value_to_point};
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
use std::f64::NAN;
@ -691,7 +690,7 @@ pub fn create_proto<'gc>(
"toString",
to_string,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -699,7 +698,7 @@ pub fn create_proto<'gc>(
"isEmpty",
is_empty,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -707,17 +706,23 @@ pub fn create_proto<'gc>(
"setEmpty",
set_empty,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("clone", clone, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function(
"clone",
clone,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"contains",
contains,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -725,7 +730,7 @@ pub fn create_proto<'gc>(
"containsPoint",
contains_point,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -733,7 +738,7 @@ pub fn create_proto<'gc>(
"containsRectangle",
contains_rectangle,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -741,17 +746,23 @@ pub fn create_proto<'gc>(
"intersects",
intersects,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("union", union, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function(
"union",
union,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"inflate",
inflate,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -759,7 +770,7 @@ pub fn create_proto<'gc>(
"inflatePoint",
inflate_point,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -767,7 +778,7 @@ pub fn create_proto<'gc>(
"offset",
offset,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -775,7 +786,7 @@ pub fn create_proto<'gc>(
"offsetPoint",
offset_point,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -783,7 +794,7 @@ pub fn create_proto<'gc>(
"intersection",
intersection,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -791,7 +802,7 @@ pub fn create_proto<'gc>(
"equals",
equals,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -810,7 +821,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
Attribute::DontDelete | Attribute::DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
object.add_property(
@ -828,7 +839,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
Attribute::DontDelete | Attribute::DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
object.add_property(
@ -846,7 +857,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
Attribute::DontDelete | Attribute::DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
object.add_property(
@ -864,7 +875,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
Attribute::DontDelete | Attribute::DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
object.add_property(
@ -882,7 +893,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
Attribute::DontDelete | Attribute::DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
object.add_property(
@ -900,7 +911,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
Attribute::DontDelete | Attribute::DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
object.add_property(
@ -918,7 +929,7 @@ pub fn create_proto<'gc>(
Some(fn_proto),
fn_proto,
)),
Attribute::DontDelete | Attribute::DontEnum,
Attribute::DONT_DELETE | Attribute::DONT_ENUM,
);
object.into()

View File

@ -147,7 +147,7 @@ pub fn create_selection_object<'gc>(
"getBeginIndex",
get_begin_index,
gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -155,7 +155,7 @@ pub fn create_selection_object<'gc>(
"getEndIndex",
get_end_index,
gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -163,7 +163,7 @@ pub fn create_selection_object<'gc>(
"getCaretIndex",
get_caret_index,
gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -171,7 +171,7 @@ pub fn create_selection_object<'gc>(
"setSelection",
set_selection,
gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -179,7 +179,7 @@ pub fn create_selection_object<'gc>(
"setFocus",
set_focus,
gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -187,7 +187,7 @@ pub fn create_selection_object<'gc>(
"getFocus",
get_focus,
gc_context,
Attribute::DontDelete | Attribute::DontEnum | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);

View File

@ -1,10 +1,10 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value};
use crate::avm_warn;
use crate::display_object::TDisplayObject;
use enumset::EnumSet;
use gc_arena::MutationContext;
use crate::avm1::object::shared_object::SharedObject;
@ -106,7 +106,7 @@ fn deserialize_object<'gc>(
activation.context.gc_context,
entry.0,
value,
EnumSet::empty(),
Attribute::empty(),
);
}
obj.into()
@ -141,7 +141,7 @@ fn deserialize_array<'gc>(
activation.context.gc_context,
entry.0,
value,
EnumSet::empty(),
Attribute::empty(),
);
}
}
@ -282,7 +282,7 @@ pub fn get_local<'gc>(
activation.context.gc_context,
"data",
data,
EnumSet::empty(),
Attribute::empty(),
);
activation.context.shared_objects.insert(full_name, this);
@ -344,7 +344,7 @@ pub fn create_shared_object_object<'gc>(
"deleteAll",
delete_all,
gc_context,
EnumSet::empty(),
Attribute::empty(),
fn_proto,
);
@ -352,7 +352,7 @@ pub fn create_shared_object_object<'gc>(
"getDiskUsage",
get_disk_usage,
gc_context,
EnumSet::empty(),
Attribute::empty(),
fn_proto,
);
@ -360,7 +360,7 @@ pub fn create_shared_object_object<'gc>(
"getLocal",
get_local,
gc_context,
EnumSet::empty(),
Attribute::empty(),
fn_proto,
);
@ -368,7 +368,7 @@ pub fn create_shared_object_object<'gc>(
"getRemote",
get_remote,
gc_context,
EnumSet::empty(),
Attribute::empty(),
fn_proto,
);
@ -376,7 +376,7 @@ pub fn create_shared_object_object<'gc>(
"getMaxSize",
get_max_size,
gc_context,
EnumSet::empty(),
Attribute::empty(),
fn_proto,
);
@ -384,7 +384,7 @@ pub fn create_shared_object_object<'gc>(
"addListener",
add_listener,
gc_context,
EnumSet::empty(),
Attribute::empty(),
fn_proto,
);
@ -392,7 +392,7 @@ pub fn create_shared_object_object<'gc>(
"removeListener",
remove_listener,
gc_context,
EnumSet::empty(),
Attribute::empty(),
fn_proto,
);
@ -509,35 +509,53 @@ pub fn create_proto<'gc>(
let shared_obj = SharedObject::empty_shared_obj(gc_context, Some(proto));
let mut object = shared_obj.as_script_object().unwrap();
object.force_set_function("clear", clear, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function(
"clear",
clear,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("close", close, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function(
"close",
close,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"connect",
connect,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("flush", flush, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function(
"flush",
flush,
gc_context,
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"getSize",
get_size,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function("send", send, gc_context, EnumSet::empty(), Some(fn_proto));
object.force_set_function("send", send, gc_context, Attribute::empty(), Some(fn_proto));
object.force_set_function(
"setFps",
set_fps,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -545,7 +563,7 @@ pub fn create_proto<'gc>(
"onStatus",
on_status,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -553,7 +571,7 @@ pub fn create_proto<'gc>(
"onSync",
on_sync,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);

View File

@ -4,7 +4,7 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, SoundObject, TObject, Value};
use crate::avm_warn;
use crate::character::Character;
@ -44,7 +44,7 @@ pub fn create_proto<'gc>(
"attachSound",
attach_sound,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -58,7 +58,7 @@ pub fn create_proto<'gc>(
fn_proto,
),
None,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
object.add_property(
@ -71,14 +71,14 @@ pub fn create_proto<'gc>(
fn_proto,
),
None,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
object.as_script_object().unwrap().force_set_function(
"getBytesLoaded",
get_bytes_loaded,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -86,7 +86,7 @@ pub fn create_proto<'gc>(
"getBytesTotal",
get_bytes_total,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -94,7 +94,7 @@ pub fn create_proto<'gc>(
"getPan",
get_pan,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -102,7 +102,7 @@ pub fn create_proto<'gc>(
"getTransform",
get_transform,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -110,7 +110,7 @@ pub fn create_proto<'gc>(
"getVolume",
get_volume,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -118,7 +118,7 @@ pub fn create_proto<'gc>(
"loadSound",
load_sound,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -132,14 +132,14 @@ pub fn create_proto<'gc>(
fn_proto,
),
None,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
object.as_script_object().unwrap().force_set_function(
"setPan",
set_pan,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -147,7 +147,7 @@ pub fn create_proto<'gc>(
"setTransform",
set_transform,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -155,7 +155,7 @@ pub fn create_proto<'gc>(
"setVolume",
set_volume,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -163,7 +163,7 @@ pub fn create_proto<'gc>(
"start",
start,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -171,7 +171,7 @@ pub fn create_proto<'gc>(
"stop",
stop,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);

View File

@ -36,7 +36,7 @@ pub fn create_stage_object<'gc>(
Some(fn_proto),
fn_proto,
)),
Attribute::DontEnum | Attribute::DontDelete,
Attribute::DONT_ENUM | Attribute::DONT_DELETE,
);
stage.add_property(
@ -49,7 +49,7 @@ pub fn create_stage_object<'gc>(
fn_proto,
),
None,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
stage.add_property(
@ -67,7 +67,7 @@ pub fn create_stage_object<'gc>(
Some(fn_proto),
fn_proto,
)),
Attribute::DontEnum | Attribute::DontDelete,
Attribute::DONT_ENUM | Attribute::DONT_DELETE,
);
stage.add_property(
@ -85,7 +85,7 @@ pub fn create_stage_object<'gc>(
Some(fn_proto),
fn_proto,
)),
Attribute::DontEnum | Attribute::DontDelete,
Attribute::DONT_ENUM | Attribute::DONT_DELETE,
);
stage.add_property(
@ -98,7 +98,7 @@ pub fn create_stage_object<'gc>(
fn_proto,
),
None,
Attribute::DontEnum | Attribute::DontDelete | Attribute::ReadOnly,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
stage.into()

View File

@ -4,10 +4,9 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::value_object::ValueObject;
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use crate::string_utils;
use enumset::EnumSet;
use gc_arena::MutationContext;
/// `String` constructor
@ -64,7 +63,7 @@ pub fn create_string_object<'gc>(
"fromCharCode",
from_char_code,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
@ -84,28 +83,28 @@ pub fn create_proto<'gc>(
"toString",
to_string_value_of,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"valueOf",
to_string_value_of,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
object.force_set_function(
"charAt",
char_at,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
object.force_set_function(
"charCodeAt",
char_code_at,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -113,7 +112,7 @@ pub fn create_proto<'gc>(
"concat",
concat,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -121,7 +120,7 @@ pub fn create_proto<'gc>(
"indexOf",
index_of,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -129,7 +128,7 @@ pub fn create_proto<'gc>(
"lastIndexOf",
last_index_of,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -137,7 +136,7 @@ pub fn create_proto<'gc>(
"slice",
slice,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -145,7 +144,7 @@ pub fn create_proto<'gc>(
"split",
split,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -153,7 +152,7 @@ pub fn create_proto<'gc>(
"substr",
substr,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -161,7 +160,7 @@ pub fn create_proto<'gc>(
"substring",
substring,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -169,7 +168,7 @@ pub fn create_proto<'gc>(
"toLowerCase",
to_lower_case,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);
@ -177,7 +176,7 @@ pub fn create_proto<'gc>(
"toUpperCase",
to_upper_case,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
Some(fn_proto),
);

View File

@ -2,10 +2,11 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::Object;
use crate::avm1::property::Attribute;
use crate::avm1::{Avm1, ScriptObject, TObject, Value};
use crate::avm_warn;
use bitflags::bitflags;
use core::fmt;
use enumset::{EnumSet, EnumSetType};
use gc_arena::MutationContext;
use num_enum::TryFromPrimitive;
use std::convert::TryFrom;
@ -214,28 +215,29 @@ enum SettingsPanel {
Camera = 3,
}
#[derive(EnumSetType, Debug)]
pub enum SystemCapabilities {
AvHardware,
Accessibility,
Audio,
AudioEncoder,
EmbeddedVideo,
IME,
MP3,
Printing,
ScreenBroadcast,
ScreenPlayback,
StreamingAudio,
StreamingVideo,
VideoEncoder,
Debugger,
LocalFileRead,
Process64Bit,
Process32Bit,
AcrobatEmbedded,
TLS,
WindowLess,
bitflags! {
pub struct SystemCapabilities: u32 {
const AV_HARDWARE = 1 << 0;
const ACCESSIBILITY = 1 << 1;
const AUDIO = 1 << 2;
const AUDIO_ENCODER = 1 << 3;
const EMBEDDED_VIDEO = 1 << 4;
const IME = 1 << 5;
const MP3 = 1 << 6;
const PRINTING = 1 << 7;
const SCREEN_BROADCAST = 1 << 8;
const SCREEN_PLAYBACK = 1 << 9;
const STREAMING_AUDIO = 1 << 10;
const STREAMING_VIDEO = 1 << 11;
const VIDEO_ENCODER = 1 << 12;
const DEBUGGER = 1 << 13;
const LOCAL_FILE_READ = 1 << 14;
const PROCESS_64_BIT = 1 << 15;
const PROCESS_32_BIT = 1 << 16;
const ACROBAT_EMBEDDED = 1 << 17;
const TLS = 1 << 18;
const WINDOW_LESS = 1 << 19;
}
}
/// The properties modified by 'System'
@ -247,7 +249,7 @@ pub struct SystemProperties {
/// If false then unicode should be used
pub use_codepage: bool,
/// The capabilities of the player
pub capabilities: EnumSet<SystemCapabilities>,
pub capabilities: SystemCapabilities,
/// The type of the player
pub player_type: PlayerType,
/// The type of screen available to the player
@ -307,42 +309,42 @@ impl SystemProperties {
pub fn get_server_string(&self, avm: &mut Avm1) -> String {
url::form_urlencoded::Serializer::new(String::new())
.append_pair("A", self.encode_capability(SystemCapabilities::Audio))
.append_pair("A", self.encode_capability(SystemCapabilities::AUDIO))
.append_pair(
"SA",
self.encode_capability(SystemCapabilities::StreamingAudio),
self.encode_capability(SystemCapabilities::STREAMING_AUDIO),
)
.append_pair(
"SV",
self.encode_capability(SystemCapabilities::StreamingVideo),
self.encode_capability(SystemCapabilities::STREAMING_VIDEO),
)
.append_pair(
"EV",
self.encode_capability(SystemCapabilities::EmbeddedVideo),
self.encode_capability(SystemCapabilities::EMBEDDED_VIDEO),
)
.append_pair("MP3", self.encode_capability(SystemCapabilities::MP3))
.append_pair(
"AE",
self.encode_capability(SystemCapabilities::AudioEncoder),
self.encode_capability(SystemCapabilities::AUDIO_ENCODER),
)
.append_pair(
"VE",
self.encode_capability(SystemCapabilities::VideoEncoder),
self.encode_capability(SystemCapabilities::VIDEO_ENCODER),
)
.append_pair(
"ACC",
self.encode_not_capability(SystemCapabilities::Accessibility),
self.encode_not_capability(SystemCapabilities::ACCESSIBILITY),
)
.append_pair("PR", self.encode_capability(SystemCapabilities::Printing))
.append_pair("PR", self.encode_capability(SystemCapabilities::PRINTING))
.append_pair(
"SP",
self.encode_capability(SystemCapabilities::ScreenPlayback),
self.encode_capability(SystemCapabilities::SCREEN_PLAYBACK),
)
.append_pair(
"SB",
self.encode_capability(SystemCapabilities::ScreenBroadcast),
self.encode_capability(SystemCapabilities::SCREEN_BROADCAST),
)
.append_pair("DEB", self.encode_capability(SystemCapabilities::Debugger))
.append_pair("DEB", self.encode_capability(SystemCapabilities::DEBUGGER))
.append_pair(
"M",
&self.encode_string(
@ -363,11 +365,11 @@ impl SystemProperties {
.append_pair("PT", &self.player_type.to_string())
.append_pair(
"AVD",
self.encode_not_capability(SystemCapabilities::AvHardware),
self.encode_not_capability(SystemCapabilities::AV_HARDWARE),
)
.append_pair(
"LFD",
self.encode_not_capability(SystemCapabilities::LocalFileRead),
self.encode_not_capability(SystemCapabilities::LOCAL_FILE_READ),
)
.append_pair("DP", &self.dpi.to_string())
.finish()
@ -381,7 +383,7 @@ impl Default for SystemProperties {
exact_settings: true,
//TODO: default to false on fp>=7, true <= 6
use_codepage: false,
capabilities: EnumSet::empty(),
capabilities: SystemCapabilities::empty(),
player_type: PlayerType::StandAlone,
screen_color: ScreenColor::Color,
// TODO: note for fp <7 this should be the locale and the ui lang for >= 7, on windows
@ -519,7 +521,7 @@ pub fn create<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
system.add_property(
@ -537,25 +539,25 @@ pub fn create<'gc>(
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
Attribute::empty(),
);
system.define_value(gc_context, "security", security.into(), EnumSet::empty());
system.define_value(gc_context, "security", security.into(), Attribute::empty());
system.define_value(
gc_context,
"capabilities",
capabilities.into(),
EnumSet::empty(),
Attribute::empty(),
);
system.define_value(gc_context, "IME", ime.into(), EnumSet::empty());
system.define_value(gc_context, "IME", ime.into(), Attribute::empty());
system.force_set_function(
"setClipboard",
set_clipboard,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -563,7 +565,7 @@ pub fn create<'gc>(
"showSettings",
show_settings,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -572,7 +574,7 @@ pub fn create<'gc>(
"onStatus",
on_status,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);

View File

@ -3,8 +3,8 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::system::SystemCapabilities;
use crate::avm1::object::Object;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
macro_rules! capabilities_func {
@ -39,39 +39,42 @@ macro_rules! capabilities_prop {
$name,
FunctionObject::function($gc_ctx, Executable::Native($func), Some($fn_proto), $fn_proto),
None,
EnumSet::empty()
Attribute::empty()
);
)*
}};
}
capabilities_func!(get_has_64_bit_support, SystemCapabilities::Process64Bit);
capabilities_func!(get_has_32_bit_support, SystemCapabilities::Process32Bit);
capabilities_func!(get_is_acrobat_embedded, SystemCapabilities::AcrobatEmbedded);
capabilities_func!(get_has_64_bit_support, SystemCapabilities::PROCESS_64_BIT);
capabilities_func!(get_has_32_bit_support, SystemCapabilities::PROCESS_32_BIT);
capabilities_func!(
get_is_acrobat_embedded,
SystemCapabilities::ACROBAT_EMBEDDED
);
capabilities_func!(get_has_tls, SystemCapabilities::TLS);
capabilities_func!(get_has_accessibility, SystemCapabilities::Accessibility);
capabilities_func!(get_has_audio, SystemCapabilities::Audio);
capabilities_func!(get_has_audio_encoder, SystemCapabilities::AudioEncoder);
capabilities_func!(get_has_embedded_video, SystemCapabilities::EmbeddedVideo);
capabilities_func!(get_has_accessibility, SystemCapabilities::ACCESSIBILITY);
capabilities_func!(get_has_audio, SystemCapabilities::AUDIO);
capabilities_func!(get_has_audio_encoder, SystemCapabilities::AUDIO_ENCODER);
capabilities_func!(get_has_embedded_video, SystemCapabilities::EMBEDDED_VIDEO);
capabilities_func!(get_has_ime, SystemCapabilities::IME);
capabilities_func!(get_has_mp3, SystemCapabilities::MP3);
capabilities_func!(get_has_printing, SystemCapabilities::Printing);
capabilities_func!(get_has_printing, SystemCapabilities::PRINTING);
capabilities_func!(
get_has_screen_broadcast,
SystemCapabilities::ScreenBroadcast
SystemCapabilities::SCREEN_BROADCAST
);
capabilities_func!(get_has_screen_playback, SystemCapabilities::ScreenPlayback);
capabilities_func!(get_has_streaming_audio, SystemCapabilities::StreamingAudio);
capabilities_func!(get_has_streaming_video, SystemCapabilities::StreamingVideo);
capabilities_func!(get_has_video_encoder, SystemCapabilities::VideoEncoder);
capabilities_func!(get_is_debugger, SystemCapabilities::Debugger);
capabilities_func!(get_has_screen_playback, SystemCapabilities::SCREEN_PLAYBACK);
capabilities_func!(get_has_streaming_audio, SystemCapabilities::STREAMING_AUDIO);
capabilities_func!(get_has_streaming_video, SystemCapabilities::STREAMING_VIDEO);
capabilities_func!(get_has_video_encoder, SystemCapabilities::VIDEO_ENCODER);
capabilities_func!(get_is_debugger, SystemCapabilities::DEBUGGER);
inverse_capabilities_func!(
get_is_local_file_read_disabled,
SystemCapabilities::LocalFileRead
SystemCapabilities::LOCAL_FILE_READ
);
inverse_capabilities_func!(get_is_av_hardware_disabled, SystemCapabilities::AvHardware);
inverse_capabilities_func!(get_is_windowless_disabled, SystemCapabilities::WindowLess);
inverse_capabilities_func!(get_is_av_hardware_disabled, SystemCapabilities::AV_HARDWARE);
inverse_capabilities_func!(get_is_windowless_disabled, SystemCapabilities::WINDOW_LESS);
pub fn get_player_type<'gc>(
activation: &mut Activation<'_, 'gc, '_>,

View File

@ -3,7 +3,6 @@ use crate::avm1::error::Error;
use crate::avm1::globals::as_broadcaster::BroadcasterFunctions;
use crate::avm1::object::Object;
use crate::avm1::property::Attribute;
use crate::avm1::property::Attribute::{DontDelete, DontEnum, ReadOnly};
use crate::avm1::{ScriptObject, TObject, Value};
use gc_arena::MutationContext;
use std::convert::Into;
@ -79,56 +78,56 @@ pub fn create<'gc>(
gc_context,
"ALPHANUMERIC_FULL",
"ALPHANUMERIC_FULL".into(),
Attribute::DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
ime.define_value(
gc_context,
"ALPHANUMERIC_HALF",
"ALPHANUMERIC_HALF".into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
ime.define_value(
gc_context,
"CHINESE",
"CHINESE".into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
ime.define_value(
gc_context,
"JAPANESE_HIRAGANA",
"JAPANESE_HIRAGANA".into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
ime.define_value(
gc_context,
"JAPANESE_KATAKANA_FULL",
"JAPANESE_KATAKANA_FULL".into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
ime.define_value(
gc_context,
"KOREAN",
"KOREAN".into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
ime.define_value(
gc_context,
"UNKNOWN",
"UNKNOWN".into(),
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
);
ime.force_set_function(
"onIMEComposition",
on_ime_composition,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
@ -136,7 +135,7 @@ pub fn create<'gc>(
"doConversion",
do_conversion,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
@ -144,7 +143,7 @@ pub fn create<'gc>(
"getConversionMode",
get_conversion_mode,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
@ -152,7 +151,7 @@ pub fn create<'gc>(
"getEnabled",
get_enabled,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
@ -160,7 +159,7 @@ pub fn create<'gc>(
"setCompositionString",
set_composition_string,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
@ -168,7 +167,7 @@ pub fn create<'gc>(
"setConversionMode",
set_conversion_mode,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);
@ -176,7 +175,7 @@ pub fn create<'gc>(
"setEnabled",
set_enabled,
gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
fn_proto,
);

View File

@ -2,9 +2,9 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::Object;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, ScriptObject, TObject, Value};
use crate::avm_warn;
use enumset::EnumSet;
use gc_arena::MutationContext;
use std::convert::Into;
@ -97,7 +97,7 @@ pub fn create<'gc>(
"PolicyFileResolver",
policy_file_resolver,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -105,7 +105,7 @@ pub fn create<'gc>(
"allowDomain",
allow_domain,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -113,7 +113,7 @@ pub fn create<'gc>(
"allowInsecureDomain",
allow_insecure_domain,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -121,7 +121,7 @@ pub fn create<'gc>(
"loadPolicyFile",
load_policy_file,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -129,7 +129,7 @@ pub fn create<'gc>(
"escapeDomain",
escape_domain,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -143,7 +143,7 @@ pub fn create<'gc>(
fn_proto,
),
None,
EnumSet::empty(),
Attribute::empty(),
);
security.add_property(
@ -156,7 +156,7 @@ pub fn create<'gc>(
fn_proto,
),
None,
EnumSet::empty(),
Attribute::empty(),
);
security.into()

View File

@ -2,7 +2,7 @@ use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::display_object;
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use crate::avm_error;
use crate::display_object::{AutoSizeMode, EditText, TDisplayObject, TextSelection};
@ -23,7 +23,7 @@ macro_rules! with_text_field {
Ok(Value::Undefined)
} as crate::avm1::function::NativeFunction<'gc>,
$gc_context,
DontDelete | ReadOnly | DontEnum,
Attribute::DONT_DELETE | Attribute::READ_ONLY | Attribute::DONT_ENUM,
$fn_proto
);
)*
@ -38,7 +38,7 @@ macro_rules! with_text_field_props {
$name,
with_text_field_props!(getter $gc, $fn_proto, $get),
with_text_field_props!(setter $gc, $fn_proto, $($set),*),
Default::default()
Attribute::empty()
);
)*
};

View File

@ -5,9 +5,9 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::{color_transform, matrix};
use crate::avm1::object::transform_object::TransformObject;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, TObject, Value};
use crate::display_object::{DisplayObject, MovieClip, TDisplayObject};
use enumset::EnumSet;
use gc_arena::MutationContext;
macro_rules! with_transform_props {
@ -18,7 +18,7 @@ macro_rules! with_transform_props {
$name,
with_transform_props!(getter $gc, $fn_proto, $get),
with_transform_props!(setter $gc, $fn_proto, $($set),*),
EnumSet::empty(),
Attribute::empty(),
);
)*
};

View File

@ -5,13 +5,12 @@ use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::script_object::ScriptObject;
use crate::avm1::object::xml_object::XMLObject;
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, TObject, Value};
use crate::avm_warn;
use crate::backend::navigator::RequestOptions;
use crate::xml;
use crate::xml::{XMLDocument, XMLNode};
use enumset::EnumSet;
use gc_arena::MutationContext;
use quick_xml::Error as ParseError;
@ -550,7 +549,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto.add_property(
gc_context,
@ -562,7 +561,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto.add_property(
gc_context,
@ -574,7 +573,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto.add_property(
gc_context,
@ -586,7 +585,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto.add_property(
gc_context,
@ -598,7 +597,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto.add_property(
gc_context,
@ -610,7 +609,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto.add_property(
gc_context,
@ -622,7 +621,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto.add_property(
gc_context,
@ -634,7 +633,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto.add_property(
gc_context,
@ -646,7 +645,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto.add_property(
gc_context,
@ -658,7 +657,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto.add_property(
gc_context,
@ -670,7 +669,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto.add_property(
gc_context,
@ -682,7 +681,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto.add_property(
gc_context,
@ -694,7 +693,7 @@ pub fn create_xmlnode_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xmlnode_proto
.as_script_object()
@ -703,7 +702,7 @@ pub fn create_xmlnode_proto<'gc>(
"appendChild",
xmlnode_append_child,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
xmlnode_proto
@ -713,7 +712,7 @@ pub fn create_xmlnode_proto<'gc>(
"insertBefore",
xmlnode_insert_before,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
xmlnode_proto
@ -723,7 +722,7 @@ pub fn create_xmlnode_proto<'gc>(
"cloneNode",
xmlnode_clone_node,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
xmlnode_proto
@ -733,7 +732,7 @@ pub fn create_xmlnode_proto<'gc>(
"getNamespaceForPrefix",
xmlnode_get_namespace_for_prefix,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
xmlnode_proto
@ -743,7 +742,7 @@ pub fn create_xmlnode_proto<'gc>(
"getPrefixForNamespace",
xmlnode_get_prefix_for_namespace,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
xmlnode_proto
@ -753,7 +752,7 @@ pub fn create_xmlnode_proto<'gc>(
"hasChildNodes",
xmlnode_has_child_nodes,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
xmlnode_proto
@ -763,7 +762,7 @@ pub fn create_xmlnode_proto<'gc>(
"removeNode",
xmlnode_remove_node,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
xmlnode_proto
@ -773,7 +772,7 @@ pub fn create_xmlnode_proto<'gc>(
"toString",
xmlnode_to_string,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
@ -1091,9 +1090,9 @@ pub fn create_xml_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xml_proto.define_value(gc_context, "ignoreWhite", false.into(), EnumSet::empty());
xml_proto.define_value(gc_context, "ignoreWhite", false.into(), Attribute::empty());
xml_proto.add_property(
gc_context,
"xmlDecl",
@ -1104,7 +1103,7 @@ pub fn create_xml_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xml_proto.add_property(
gc_context,
@ -1116,7 +1115,7 @@ pub fn create_xml_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xml_proto.add_property(
gc_context,
@ -1128,41 +1127,41 @@ pub fn create_xml_proto<'gc>(
fn_proto,
),
None,
ReadOnly.into(),
Attribute::READ_ONLY,
);
xml_proto.as_script_object().unwrap().force_set_function(
"createElement",
xml_create_element,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
xml_proto.as_script_object().unwrap().force_set_function(
"createTextNode",
xml_create_text_node,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
xml_proto.as_script_object().unwrap().force_set_function(
"parseXML",
xml_parse_xml,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
xml_proto.as_script_object().unwrap().force_set_function(
"load",
xml_load,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);
xml_proto.as_script_object().unwrap().force_set_function(
"onData",
xml_on_data,
gc_context,
EnumSet::empty(),
Attribute::empty(),
Some(fn_proto),
);

View File

@ -28,7 +28,6 @@ use crate::avm1::{ScriptObject, SoundObject, StageObject, Value};
use crate::avm_warn;
use crate::display_object::DisplayObject;
use crate::xml::XMLNode;
use enumset::EnumSet;
use gc_arena::{Collect, MutationContext};
use ruffle_macros::enum_trait_object;
use std::borrow::Cow;
@ -249,7 +248,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
gc_context: MutationContext<'gc, '_>,
name: &str,
value: Value<'gc>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
);
/// Set the attributes of a given property.
@ -263,8 +262,8 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
&self,
gc_context: MutationContext<'gc, '_>,
name: Option<&str>,
set_attributes: EnumSet<Attribute>,
clear_attributes: EnumSet<Attribute>,
set_attributes: Attribute,
clear_attributes: Attribute,
);
/// Define a virtual property onto a given object.
@ -283,7 +282,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
name: &str,
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
);
/// Define a virtual property onto a given object.
@ -303,7 +302,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
name: &str,
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
);
/// Set the 'watcher' of a given property.

View File

@ -58,7 +58,7 @@ macro_rules! impl_custom_object_without_set {
gc_context: gc_arena::MutationContext<'gc, '_>,
name: &str,
value: crate::avm1::Value<'gc>,
attributes: enumset::EnumSet<crate::avm1::property::Attribute>,
attributes: crate::avm1::property::Attribute,
) {
self.0
.read()
@ -70,8 +70,8 @@ macro_rules! impl_custom_object_without_set {
&self,
gc_context: gc_arena::MutationContext<'gc, '_>,
name: Option<&str>,
set_attributes: enumset::EnumSet<crate::avm1::property::Attribute>,
clear_attributes: enumset::EnumSet<crate::avm1::property::Attribute>,
set_attributes: crate::avm1::property::Attribute,
clear_attributes: crate::avm1::property::Attribute,
) {
self.0.write(gc_context).$field.set_attributes(
gc_context,
@ -87,7 +87,7 @@ macro_rules! impl_custom_object_without_set {
name: &str,
get: crate::avm1::object::Object<'gc>,
set: Option<crate::avm1::object::Object<'gc>>,
attributes: enumset::EnumSet<crate::avm1::property::Attribute>,
attributes: crate::avm1::property::Attribute,
) {
self.0
.read()
@ -102,7 +102,7 @@ macro_rules! impl_custom_object_without_set {
name: &str,
get: crate::avm1::object::Object<'gc>,
set: Option<crate::avm1::object::Object<'gc>>,
attributes: enumset::EnumSet<crate::avm1::property::Attribute>,
attributes: crate::avm1::property::Attribute,
) {
self.0
.read()
@ -268,7 +268,6 @@ macro_rules! add_field_accessors {
);
};
($([$var: ident, $type_: ty $(, set => $set_ident: ident)? $(, get => $get_ident: ident)?],)*) => {
$(
$( add_field_accessors!([setter_only $set_ident, $var, $type_],); )*

View File

@ -5,7 +5,6 @@ use crate::avm1::property::{Attribute, Property};
use crate::avm1::{AvmString, Object, ObjectPtr, TObject, Value};
use crate::property_map::{Entry, PropertyMap};
use core::fmt;
use enumset::EnumSet;
use gc_arena::{Collect, GcCell, MutationContext};
use std::borrow::Cow;
@ -185,16 +184,14 @@ impl<'gc> ScriptObject<'gc> {
/// is only possible when defining host functions. User-defined functions
/// always get a fresh explicit prototype, so you should never force set a
/// user-defined function.
pub fn force_set_function<A>(
pub fn force_set_function(
&mut self,
name: &str,
function: NativeFunction<'gc>,
gc_context: MutationContext<'gc, '_>,
attributes: A,
attributes: Attribute,
fn_proto: Option<Object<'gc>>,
) where
A: Into<EnumSet<Attribute>>,
{
) {
self.define_value(
gc_context,
name,
@ -205,7 +202,7 @@ impl<'gc> ScriptObject<'gc> {
fn_proto,
)
.into(),
attributes.into(),
attributes,
)
}
@ -239,9 +236,9 @@ impl<'gc> ScriptObject<'gc> {
entry.insert(Property::Stored {
value: native_value,
attributes: if is_enumerable {
EnumSet::empty()
Attribute::empty()
} else {
Attribute::DontEnum.into()
Attribute::DONT_ENUM
},
});
}
@ -354,7 +351,7 @@ impl<'gc> ScriptObject<'gc> {
Entry::Vacant(entry) => {
entry.insert(Property::Stored {
value: value.clone(),
attributes: Default::default(),
attributes: Attribute::empty(),
});
None
@ -529,7 +526,7 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
name: &str,
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.0.write(gc_context).values.insert(
name,
@ -549,7 +546,7 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
name: &str,
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.0.write(gc_context).values.insert(
name,
@ -596,7 +593,7 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
gc_context: MutationContext<'gc, '_>,
name: &str,
value: Value<'gc>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.0
.write(gc_context)
@ -608,8 +605,8 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
&self,
gc_context: MutationContext<'gc, '_>,
name: Option<&str>,
set_attributes: EnumSet<Attribute>,
clear_attributes: EnumSet<Attribute>,
set_attributes: Attribute,
clear_attributes: Attribute,
) {
match name {
None => {
@ -841,7 +838,7 @@ mod tests {
use crate::avm1::activation::ActivationIdentifier;
use crate::avm1::function::Executable;
use crate::avm1::globals::system::SystemProperties;
use crate::avm1::property::Attribute::*;
use crate::avm1::property::Attribute;
use crate::avm1::{Avm1, Timers};
use crate::avm2::Avm2;
use crate::backend::audio::NullAudioBackend;
@ -955,7 +952,7 @@ mod tests {
activation.context.gc_context,
"forced",
"forced".into(),
EnumSet::empty(),
Attribute::empty(),
);
object.set("natural", "natural".into(), activation).unwrap();
@ -971,13 +968,13 @@ mod tests {
activation.context.gc_context,
"normal",
"initial".into(),
EnumSet::empty(),
Attribute::empty(),
);
object.as_script_object().unwrap().define_value(
activation.context.gc_context,
"readonly",
"initial".into(),
ReadOnly.into(),
Attribute::READ_ONLY,
);
object.set("normal", "replaced".into(), activation).unwrap();
@ -1000,7 +997,7 @@ mod tests {
activation.context.gc_context,
"test",
"initial".into(),
DontDelete.into(),
Attribute::DONT_DELETE,
);
assert_eq!(object.delete(activation, "test"), false);
@ -1032,7 +1029,7 @@ mod tests {
"test",
getter,
None,
EnumSet::empty(),
Attribute::empty(),
);
assert_eq!(object.get("test", activation).unwrap(), "Virtual!".into());
@ -1058,26 +1055,26 @@ mod tests {
"virtual",
getter,
None,
EnumSet::empty(),
Attribute::empty(),
);
object.as_script_object().unwrap().add_property(
activation.context.gc_context,
"virtual_un",
getter,
None,
DontDelete.into(),
Attribute::DONT_DELETE,
);
object.as_script_object().unwrap().define_value(
activation.context.gc_context,
"stored",
"Stored!".into(),
EnumSet::empty(),
Attribute::empty(),
);
object.as_script_object().unwrap().define_value(
activation.context.gc_context,
"stored_un",
"Stored!".into(),
DontDelete.into(),
Attribute::DONT_DELETE,
);
assert_eq!(object.delete(activation, "virtual"), true);
@ -1113,27 +1110,27 @@ mod tests {
activation.context.gc_context,
"stored",
Value::Null,
EnumSet::empty(),
Attribute::empty(),
);
object.as_script_object().unwrap().define_value(
activation.context.gc_context,
"stored_hidden",
Value::Null,
DontEnum.into(),
Attribute::DONT_ENUM,
);
object.as_script_object().unwrap().add_property(
activation.context.gc_context,
"virtual",
getter,
None,
EnumSet::empty(),
Attribute::empty(),
);
object.as_script_object().unwrap().add_property(
activation.context.gc_context,
"virtual_hidden",
getter,
None,
DontEnum.into(),
Attribute::DONT_ENUM,
);
let keys: Vec<_> = object.get_keys(activation);

View File

@ -11,7 +11,6 @@ use crate::context::UpdateContext;
use crate::display_object::{DisplayObject, EditText, MovieClip, TDisplayObjectContainer};
use crate::property_map::PropertyMap;
use crate::types::Percent;
use enumset::EnumSet;
use gc_arena::{Collect, GcCell, MutationContext};
use std::borrow::Cow;
use std::fmt;
@ -268,7 +267,7 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
gc_context: MutationContext<'gc, '_>,
name: &str,
value: Value<'gc>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.0
.read()
@ -280,8 +279,8 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
&self,
gc_context: MutationContext<'gc, '_>,
name: Option<&str>,
set_attributes: EnumSet<Attribute>,
clear_attributes: EnumSet<Attribute>,
set_attributes: Attribute,
clear_attributes: Attribute,
) {
self.0.write(gc_context).base.set_attributes(
gc_context,
@ -297,7 +296,7 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
name: &str,
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.0
.read()
@ -312,7 +311,7 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
name: &str,
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.0
.read()

View File

@ -9,7 +9,6 @@ use crate::avm1::property::Attribute;
use crate::avm1::{Object, ObjectPtr, ScriptObject, TObject, Value};
use crate::avm_warn;
use crate::display_object::DisplayObject;
use enumset::EnumSet;
use gc_arena::{Collect, GcCell, MutationContext};
use std::borrow::Cow;
@ -181,7 +180,7 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> {
_gc_context: MutationContext<'gc, '_>,
_name: &str,
_value: Value<'gc>,
_attributes: EnumSet<Attribute>,
_attributes: Attribute,
) {
//`super` cannot have values defined on it
}
@ -190,8 +189,8 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> {
&self,
_gc_context: MutationContext<'gc, '_>,
_name: Option<&str>,
_set_attributes: EnumSet<Attribute>,
_clear_attributes: EnumSet<Attribute>,
_set_attributes: Attribute,
_clear_attributes: Attribute,
) {
//TODO: Does ASSetPropFlags work on `super`? What would it even work on?
}
@ -202,7 +201,7 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> {
_name: &str,
_get: Object<'gc>,
_set: Option<Object<'gc>>,
_attributes: EnumSet<Attribute>,
_attributes: Attribute,
) {
//`super` cannot have properties defined on it
}
@ -214,7 +213,7 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> {
_name: &str,
_get: Object<'gc>,
_set: Option<Object<'gc>>,
_attributes: EnumSet<Attribute>,
_attributes: Attribute,
) {
//`super` cannot have properties defined on it
}

View File

@ -6,7 +6,6 @@ use crate::avm1::object::{ObjectPtr, TObject};
use crate::avm1::property::Attribute;
use crate::avm1::{AvmString, Object, ScriptObject, Value};
use crate::xml::{XMLName, XMLNode};
use enumset::EnumSet;
use gc_arena::{Collect, MutationContext};
use std::borrow::Cow;
use std::fmt;
@ -126,7 +125,7 @@ impl<'gc> TObject<'gc> for XMLAttributesObject<'gc> {
name: &str,
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.base()
.add_property(gc_context, name, get, set, attributes)
@ -139,7 +138,7 @@ impl<'gc> TObject<'gc> for XMLAttributesObject<'gc> {
name: &str,
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.base()
.add_property_with_case(activation, gc_context, name, get, set, attributes)
@ -171,7 +170,7 @@ impl<'gc> TObject<'gc> for XMLAttributesObject<'gc> {
gc_context: MutationContext<'gc, '_>,
name: &str,
value: Value<'gc>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.base()
.define_value(gc_context, name, value, attributes)
@ -181,8 +180,8 @@ impl<'gc> TObject<'gc> for XMLAttributesObject<'gc> {
&self,
gc_context: MutationContext<'gc, '_>,
name: Option<&str>,
set_attributes: EnumSet<Attribute>,
clear_attributes: EnumSet<Attribute>,
set_attributes: Attribute,
clear_attributes: Attribute,
) {
self.base()
.set_attributes(gc_context, name, set_attributes, clear_attributes)

View File

@ -7,7 +7,6 @@ use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, Value};
use crate::avm_warn;
use crate::xml::{XMLDocument, XMLNode};
use enumset::EnumSet;
use gc_arena::{Collect, MutationContext};
use std::borrow::Cow;
use std::fmt;
@ -124,7 +123,7 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> {
name: &str,
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.base()
.add_property(gc_context, name, get, set, attributes)
@ -137,7 +136,7 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> {
name: &str,
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.base()
.add_property_with_case(activation, gc_context, name, get, set, attributes)
@ -169,7 +168,7 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> {
gc_context: MutationContext<'gc, '_>,
name: &str,
value: Value<'gc>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
) {
self.base()
.define_value(gc_context, name, value, attributes)
@ -179,8 +178,8 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> {
&self,
gc_context: MutationContext<'gc, '_>,
name: Option<&str>,
set_attributes: EnumSet<Attribute>,
clear_attributes: EnumSet<Attribute>,
set_attributes: Attribute,
clear_attributes: Attribute,
) {
self.base()
.set_attributes(gc_context, name, set_attributes, clear_attributes)

View File

@ -1,18 +1,18 @@
//! User-defined properties
use self::Attribute::*;
use crate::avm1::object::Object;
use crate::avm1::Value;
use bitflags::bitflags;
use core::fmt;
use enumset::{EnumSet, EnumSetType};
/// Attributes of properties in the AVM runtime.
/// The order is significant and should match the order used by `object::as_set_prop_flags`.
#[derive(EnumSetType, Debug)]
pub enum Attribute {
DontEnum,
DontDelete,
ReadOnly,
bitflags! {
/// Attributes of properties in the AVM runtime.
/// The values are significant and should match the order used by `object::as_set_prop_flags`.
pub struct Attribute: u8 {
const DONT_ENUM = 1 << 0;
const DONT_DELETE = 1 << 1;
const READ_ONLY = 1 << 2;
}
}
#[allow(clippy::large_enum_variant)]
@ -21,11 +21,11 @@ pub enum Property<'gc> {
Virtual {
get: Object<'gc>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
},
Stored {
value: Value<'gc>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
},
}
@ -47,7 +47,7 @@ impl<'gc> Property<'gc> {
Property::Stored {
value, attributes, ..
} => {
if !attributes.contains(ReadOnly) {
if !attributes.contains(Attribute::READ_ONLY) {
*value = new_value.into();
}
@ -57,7 +57,7 @@ impl<'gc> Property<'gc> {
}
/// List this property's attributes.
pub fn attributes(&self) -> EnumSet<Attribute> {
pub fn attributes(&self) -> Attribute {
match self {
Property::Virtual { attributes, .. } => *attributes,
Property::Stored { attributes, .. } => *attributes,
@ -65,7 +65,7 @@ impl<'gc> Property<'gc> {
}
/// Re-define this property's attributes.
pub fn set_attributes(&mut self, new_attributes: EnumSet<Attribute>) {
pub fn set_attributes(&mut self, new_attributes: Attribute) {
match self {
Property::Virtual {
ref mut attributes, ..
@ -78,15 +78,15 @@ impl<'gc> Property<'gc> {
pub fn can_delete(&self) -> bool {
match self {
Property::Virtual { attributes, .. } => !attributes.contains(DontDelete),
Property::Stored { attributes, .. } => !attributes.contains(DontDelete),
Property::Virtual { attributes, .. } => !attributes.contains(Attribute::DONT_DELETE),
Property::Stored { attributes, .. } => !attributes.contains(Attribute::DONT_DELETE),
}
}
pub fn is_enumerable(&self) -> bool {
match self {
Property::Virtual { attributes, .. } => !attributes.contains(DontEnum),
Property::Stored { attributes, .. } => !attributes.contains(DontEnum),
Property::Virtual { attributes, .. } => !attributes.contains(Attribute::DONT_ENUM),
Property::Stored { attributes, .. } => !attributes.contains(Attribute::DONT_ENUM),
}
}
@ -95,8 +95,8 @@ impl<'gc> Property<'gc> {
match self {
Property::Virtual {
attributes, set, ..
} => !attributes.contains(ReadOnly) && !set.is_none(),
Property::Stored { attributes, .. } => !attributes.contains(ReadOnly),
} => !attributes.contains(Attribute::READ_ONLY) && !set.is_none(),
Property::Stored { attributes, .. } => !attributes.contains(Attribute::READ_ONLY),
}
}

View File

@ -3,8 +3,8 @@
use crate::avm1::activation::Activation;
use crate::avm1::callable_value::CallableValue;
use crate::avm1::error::Error;
use crate::avm1::property::Attribute;
use crate::avm1::{Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::{GcCell, MutationContext};
use std::cell::Ref;
@ -307,7 +307,7 @@ impl<'gc> Scope<'gc> {
/// local object and does not traverse the scope chain.
pub fn define(&self, name: &str, value: impl Into<Value<'gc>>, mc: MutationContext<'gc, '_>) {
self.locals()
.define_value(mc, name, value.into(), EnumSet::empty());
.define_value(mc, name, value.into(), Attribute::empty());
}
/// Delete a value from scope

View File

@ -503,9 +503,10 @@ mod test {
use crate::avm1::globals::create_globals;
use crate::avm1::object::script_object::ScriptObject;
use crate::avm1::object::{Object, TObject};
use crate::avm1::property::Attribute;
use crate::avm1::test_utils::with_avm;
use crate::avm1::{AvmString, Value};
use enumset::EnumSet;
use std::f64::{INFINITY, NAN, NEG_INFINITY};
#[test]
@ -549,7 +550,7 @@ mod test {
activation.context.gc_context,
"valueOf",
valueof.into(),
EnumSet::empty(),
Attribute::empty(),
);
assert_eq!(

View File

@ -7,23 +7,24 @@ use crate::avm2::string::AvmString;
use crate::avm2::traits::{Trait, TraitKind};
use crate::avm2::{Avm2, Error};
use crate::collect::CollectWrapper;
use enumset::{EnumSet, EnumSetType};
use bitflags::bitflags;
use gc_arena::{Collect, GcCell, MutationContext};
use swf::avm2::types::{Class as AbcClass, Instance as AbcInstance};
/// All possible attributes for a given class.
#[derive(EnumSetType, Debug)]
pub enum ClassAttributes {
/// Class is sealed, attempts to set or init dynamic properties on an
/// object will generate a runtime error.
Sealed,
bitflags! {
/// All possible attributes for a given class.
pub struct ClassAttributes: u8 {
/// Class is sealed, attempts to set or init dynamic properties on an
/// object will generate a runtime error.
const SEALED = 1 << 0;
/// Class is final, attempts to construct child classes from it will
/// generate a verification error.
Final,
/// Class is final, attempts to construct child classes from it will
/// generate a verification error.
const FINAL = 1 << 1;
/// Class is an interface.
Interface,
/// Class is an interface.
const INTERFACE = 1 << 2;
}
}
/// A loaded ABC Class which can be used to construct objects with.
@ -37,7 +38,7 @@ pub struct Class<'gc> {
super_class: Option<Multiname<'gc>>,
/// Attributes of the given class.
attributes: CollectWrapper<EnumSet<ClassAttributes>>,
attributes: CollectWrapper<ClassAttributes>,
/// The namespace that protected traits of this class are stored into.
protected_namespace: Option<Namespace<'gc>>,
@ -128,7 +129,7 @@ impl<'gc> Class<'gc> {
Self {
name,
super_class,
attributes: CollectWrapper(EnumSet::empty()),
attributes: CollectWrapper(ClassAttributes::empty()),
protected_namespace: None,
interfaces: Vec::new(),
instance_init,
@ -141,7 +142,7 @@ impl<'gc> Class<'gc> {
}
/// Set the attributes of the class (sealed/final/interface status).
pub fn set_attributes(&mut self, attributes: EnumSet<ClassAttributes>) {
pub fn set_attributes(&mut self, attributes: ClassAttributes) {
self.attributes = CollectWrapper(attributes);
}
@ -202,18 +203,10 @@ impl<'gc> Class<'gc> {
let instance_init = unit.load_method(abc_instance.init_method.0, mc)?;
let class_init = unit.load_method(abc_class.init_method.0, mc)?;
let mut attributes = EnumSet::new();
if abc_instance.is_sealed {
attributes |= ClassAttributes::Sealed;
}
if abc_instance.is_final {
attributes |= ClassAttributes::Final;
}
if abc_instance.is_interface {
attributes |= ClassAttributes::Interface;
}
let mut attributes = ClassAttributes::empty();
attributes.set(ClassAttributes::SEALED, abc_instance.is_sealed);
attributes.set(ClassAttributes::FINAL, abc_instance.is_final);
attributes.set(ClassAttributes::INTERFACE, abc_instance.is_interface);
Ok(GcCell::allocate(
mc,
@ -410,6 +403,6 @@ impl<'gc> Class<'gc> {
/// Determine if this class is sealed (no dynamic properties)
pub fn is_sealed(&self) -> bool {
self.attributes.0.contains(ClassAttributes::Sealed)
self.attributes.0.contains(ClassAttributes::SEALED)
}
}

View File

@ -10,7 +10,7 @@ use crate::avm2::string::AvmString;
use crate::avm2::traits::Trait;
use crate::avm2::value::Value;
use crate::avm2::Error;
use enumset::{EnumSet, EnumSetType};
use bitflags::bitflags;
use gc_arena::{GcCell, MutationContext};
use std::cmp::{min, Ordering};
use std::mem::swap;
@ -775,25 +775,26 @@ pub fn splice<'gc>(
Ok(Value::Undefined)
}
/// The array options that a given sort operation may use.
///
/// These are provided as a number by the VM and converted into an enumset.
#[derive(EnumSetType)]
enum SortOptions {
/// Request case-insensitive string value sort.
CaseInsensitive,
bitflags! {
/// The array options that a given sort operation may use.
///
/// These are provided as a number by the VM and converted into bitflags.
struct SortOptions: u8 {
/// Request case-insensitive string value sort.
const CASE_INSENSITIVE = 1 << 0;
/// Reverse the order of sorting.
Descending,
/// Reverse the order of sorting.
const DESCENDING = 1 << 1;
/// Reject sorting on arrays with multiple equivalent values.
UniqueSort,
/// Reject sorting on arrays with multiple equivalent values.
const UNIQUE_SORT = 1 << 2;
/// Yield a list of indices rather than sorting the array in-place.
ReturnIndexedArray,
/// Yield a list of indices rather than sorting the array in-place.
const RETURN_INDEXED_ARRAY = 1 << 3;
/// Request numeric value sort.
Numeric,
/// Request numeric value sort.
const NUMERIC = 1 << 4;
}
}
/// Identity closure shim which exists purely to decorate closure types with
@ -821,7 +822,7 @@ where
fn sort_inner<'a, 'gc, 'ctxt, C>(
activation: &mut Activation<'a, 'gc, 'ctxt>,
values: &mut [(usize, Value<'gc>)],
options: EnumSet<SortOptions>,
options: SortOptions,
mut sort_func: C,
) -> Result<bool, Error>
where
@ -848,7 +849,7 @@ where
unique_sort_satisfied = false;
Ordering::Equal
}
Ok(v) if options.contains(SortOptions::Descending) => v.reverse(),
Ok(v) if options.contains(SortOptions::DESCENDING) => v.reverse(),
Ok(v) => v,
Err(e) => {
error_signal = Err(e);
@ -859,7 +860,7 @@ where
error_signal?;
Ok(!options.contains(SortOptions::UniqueSort) || unique_sort_satisfied)
Ok(!options.contains(SortOptions::UNIQUE_SORT) || unique_sort_satisfied)
}
fn compare_string_case_sensitive<'gc>(
@ -907,12 +908,12 @@ fn compare_numeric<'gc>(
fn sort_postprocess<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
options: EnumSet<SortOptions>,
options: SortOptions,
unique_satisfied: bool,
values: Vec<(usize, Value<'gc>)>,
) -> Result<Value<'gc>, Error> {
if unique_satisfied {
if options.contains(SortOptions::ReturnIndexedArray) {
if options.contains(SortOptions::RETURN_INDEXED_ARRAY) {
return build_array(
activation,
ArrayStorage::from_storage(
@ -998,18 +999,22 @@ pub fn sort<'gc>(
.unwrap_or(Value::Undefined)
.coerce_to_object(activation)?,
),
args.get(1)
.cloned()
.unwrap_or_else(|| 0.into())
.coerce_to_enumset(activation)?,
SortOptions::from_bits_truncate(
args.get(1)
.cloned()
.unwrap_or_else(|| 0.into())
.coerce_to_u32(activation)? as u8,
),
)
} else {
(
None,
args.get(0)
.cloned()
.unwrap_or_else(|| 0.into())
.coerce_to_enumset(activation)?,
SortOptions::from_bits_truncate(
args.get(0)
.cloned()
.unwrap_or_else(|| 0.into())
.coerce_to_u32(activation)? as u8,
),
)
};
@ -1042,9 +1047,9 @@ pub fn sort<'gc>(
}
}),
)?
} else if options.contains(SortOptions::Numeric) {
} else if options.contains(SortOptions::NUMERIC) {
sort_inner(activation, &mut values, options, compare_numeric)?
} else if options.contains(SortOptions::CaseInsensitive) {
} else if options.contains(SortOptions::CASE_INSENSITIVE) {
sort_inner(
activation,
&mut values,
@ -1097,23 +1102,22 @@ fn extract_maybe_array_strings<'gc>(
Ok(out)
}
/// Given a value, extract its array values and coerce them to enumsets.
/// Given a value, extract its array values and coerce them to SortOptions.
///
/// If the value is not an array, it will be returned as if it was present in a
/// one-element array containing itself. This is intended for use with parsing
/// parameters which are optionally arrays. The returned value will still be
/// coerced into a string in this case.
fn extract_maybe_array_enumsets<'gc, E>(
fn extract_maybe_array_sort_options<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
value: Value<'gc>,
) -> Result<Vec<EnumSet<E>>, Error>
where
E: EnumSetType,
{
) -> Result<Vec<SortOptions>, Error> {
let mut out = Vec::new();
for value in extract_maybe_array_values(activation, value)? {
out.push(value.coerce_to_enumset(activation)?);
out.push(SortOptions::from_bits_truncate(
value.coerce_to_u32(activation)? as u8,
));
}
Ok(out)
@ -1128,16 +1132,13 @@ pub fn sort_on<'gc>(
if let Some(this) = this {
if let Some(field_names_value) = args.get(0).cloned() {
let field_names = extract_maybe_array_strings(activation, field_names_value)?;
let mut options = extract_maybe_array_enumsets(
let mut options = extract_maybe_array_sort_options(
activation,
args.get(1).cloned().unwrap_or_else(|| 0.into()),
)?;
let first_option = options
.get(0)
.cloned()
.unwrap_or_else(EnumSet::empty)
.intersection(SortOptions::UniqueSort | SortOptions::ReturnIndexedArray);
let first_option = options.get(0).cloned().unwrap_or_else(SortOptions::empty)
& (SortOptions::UNIQUE_SORT | SortOptions::RETURN_INDEXED_ARRAY);
let mut values = if let Some(values) = extract_array_values(activation, this.into())? {
values
.iter()
@ -1151,7 +1152,7 @@ pub fn sort_on<'gc>(
if options.len() < field_names.len() {
options.resize(
field_names.len(),
options.last().cloned().unwrap_or_else(EnumSet::empty),
options.last().cloned().unwrap_or_else(SortOptions::empty),
);
}
@ -1175,9 +1176,9 @@ pub fn sort_on<'gc>(
activation,
)?;
let ord = if options.contains(SortOptions::Numeric) {
let ord = if options.contains(SortOptions::NUMERIC) {
compare_numeric(activation, a_field, b_field)?
} else if options.contains(SortOptions::CaseInsensitive) {
} else if options.contains(SortOptions::CASE_INSENSITIVE) {
compare_string_case_insensitive(activation, a_field, b_field)?
} else {
compare_string_case_sensitive(activation, a_field, b_field)?
@ -1187,7 +1188,7 @@ pub fn sort_on<'gc>(
continue;
}
if options.contains(SortOptions::Descending) {
if options.contains(SortOptions::DESCENDING) {
return Ok(ord.reverse());
} else {
return Ok(ord);
@ -1328,35 +1329,31 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
class.write(mc).define_class_trait(Trait::from_const(
QName::new(Namespace::public_namespace(), "CASEINSENSITIVE"),
Multiname::from(QName::new(Namespace::public_namespace(), "uint")),
Some(EnumSet::from(SortOptions::CaseInsensitive).as_u32().into()),
Some(SortOptions::CASE_INSENSITIVE.bits().into()),
));
class.write(mc).define_class_trait(Trait::from_const(
QName::new(Namespace::public_namespace(), "DESCENDING"),
Multiname::from(QName::new(Namespace::public_namespace(), "uint")),
Some(EnumSet::from(SortOptions::Descending).as_u32().into()),
Some(SortOptions::DESCENDING.bits().into()),
));
class.write(mc).define_class_trait(Trait::from_const(
QName::new(Namespace::public_namespace(), "NUMERIC"),
Multiname::from(QName::new(Namespace::public_namespace(), "uint")),
Some(EnumSet::from(SortOptions::Numeric).as_u32().into()),
Some(SortOptions::NUMERIC.bits().into()),
));
class.write(mc).define_class_trait(Trait::from_const(
QName::new(Namespace::public_namespace(), "RETURNINDEXEDARRAY"),
Multiname::from(QName::new(Namespace::public_namespace(), "uint")),
Some(
EnumSet::from(SortOptions::ReturnIndexedArray)
.as_u32()
.into(),
),
Some(SortOptions::RETURN_INDEXED_ARRAY.bits().into()),
));
class.write(mc).define_class_trait(Trait::from_const(
QName::new(Namespace::public_namespace(), "UNIQUESORT"),
Multiname::from(QName::new(Namespace::public_namespace(), "uint")),
Some(EnumSet::from(SortOptions::UniqueSort).as_u32().into()),
Some(SortOptions::UNIQUE_SORT.bits().into()),
));
class

View File

@ -9,8 +9,7 @@ use crate::avm2::traits::Trait;
use crate::avm2::value::Value;
use crate::avm2::Error;
use crate::context::UpdateContext;
use crate::display_object::{DisplayObject, TDisplayObject, TDisplayObjectContainer};
use enumset::EnumSet;
use crate::display_object::{DisplayObject, Lists, TDisplayObject, TDisplayObjectContainer};
use gc_arena::{GcCell, MutationContext};
use std::cmp::min;
@ -100,7 +99,7 @@ fn remove_child_from_displaylist<'gc>(
) {
if let Some(parent) = child.parent() {
if let Some(mut ctr) = parent.as_container() {
ctr.remove_child(context, child, EnumSet::all());
ctr.remove_child(context, child, Lists::all());
}
}
}
@ -353,7 +352,7 @@ pub fn remove_child_at<'gc>(
let child = ctr.child_by_index(target_child as usize).unwrap();
ctr.remove_child(&mut activation.context, child, EnumSet::all());
ctr.remove_child(&mut activation.context, child, Lists::all());
return Ok(child.object2());
}

View File

@ -272,7 +272,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
let mut write = class.write(mc);
write.set_attributes(ClassAttributes::Sealed.into());
write.set_attributes(ClassAttributes::SEALED);
write.define_instance_trait(Trait::from_getter(
QName::new(Namespace::public_namespace(), "bubbles"),

View File

@ -375,7 +375,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
let mut write = class.write(mc);
write.set_attributes(ClassAttributes::Sealed.into());
write.set_attributes(ClassAttributes::SEALED);
write.implements(QName::new(Namespace::package("flash.events"), "IEventDispatcher").into());

View File

@ -40,7 +40,7 @@ pub fn create_interface<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<
let mut write = class.write(mc);
write.set_attributes(ClassAttributes::Interface.into());
write.set_attributes(ClassAttributes::INTERFACE);
write.define_instance_trait(Trait::from_method(
QName::dynamic_name("addEventListener"),
Method::from_builtin(bodiless_method),

View File

@ -84,7 +84,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
);
let mut write = class.write(mc);
write.set_attributes(ClassAttributes::Final | ClassAttributes::Sealed);
write.set_attributes(ClassAttributes::FINAL | ClassAttributes::SEALED);
use std::f64::consts::*;
math_constants! {

View File

@ -1,20 +1,20 @@
//! Property data structures
use self::Attribute::*;
use crate::avm2::object::{Object, TObject};
use crate::avm2::return_value::ReturnValue;
use crate::avm2::value::Value;
use crate::avm2::Error;
use enumset::{EnumSet, EnumSetType};
use bitflags::bitflags;
use gc_arena::{Collect, CollectionContext};
/// Attributes of properties in the AVM runtime.
///
/// TODO: Replace with AVM2 properties for traits
#[derive(EnumSetType, Debug)]
pub enum Attribute {
DontDelete,
ReadOnly,
bitflags! {
/// Attributes of properties in the AVM runtime.
///
/// TODO: Replace with AVM2 properties for traits
pub struct Attribute: u8 {
const DONT_DELETE = 1 << 0;
const READ_ONLY = 1 << 1;
}
}
#[allow(clippy::large_enum_variant)]
@ -23,15 +23,15 @@ pub enum Property<'gc> {
Virtual {
get: Option<Object<'gc>>,
set: Option<Object<'gc>>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
},
Stored {
value: Value<'gc>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
},
Slot {
slot_id: u32,
attributes: EnumSet<Attribute>,
attributes: Attribute,
},
}
@ -53,7 +53,7 @@ impl<'gc> Property<'gc> {
pub fn new_stored(value: impl Into<Value<'gc>>) -> Self {
Property::Stored {
value: value.into(),
attributes: EnumSet::from(Attribute::DontDelete),
attributes: Attribute::DONT_DELETE,
}
}
@ -61,7 +61,7 @@ impl<'gc> Property<'gc> {
pub fn new_const(value: impl Into<Value<'gc>>) -> Self {
Property::Stored {
value: value.into(),
attributes: Attribute::ReadOnly | Attribute::DontDelete,
attributes: Attribute::DONT_DELETE | Attribute::READ_ONLY,
}
}
@ -69,17 +69,17 @@ impl<'gc> Property<'gc> {
pub fn new_dynamic_property(value: impl Into<Value<'gc>>) -> Self {
Property::Stored {
value: value.into(),
attributes: EnumSet::empty(),
attributes: Attribute::empty(),
}
}
/// Convert a function into a method.
///
/// This applies ReadOnly/DontDelete to the property.
/// This applies READ_ONLY/DONT_DELETE to the property.
pub fn new_method(fn_obj: Object<'gc>) -> Self {
Property::Stored {
value: fn_obj.into(),
attributes: Attribute::ReadOnly | Attribute::DontDelete,
attributes: Attribute::DONT_DELETE | Attribute::READ_ONLY,
}
}
@ -88,7 +88,7 @@ impl<'gc> Property<'gc> {
Property::Virtual {
get: None,
set: None,
attributes: Attribute::ReadOnly | Attribute::DontDelete,
attributes: Attribute::DONT_DELETE | Attribute::READ_ONLY,
}
}
@ -96,7 +96,7 @@ impl<'gc> Property<'gc> {
pub fn new_slot(slot_id: u32) -> Self {
Property::Slot {
slot_id,
attributes: EnumSet::from(Attribute::DontDelete),
attributes: Attribute::DONT_DELETE,
}
}
@ -185,7 +185,7 @@ impl<'gc> Property<'gc> {
Property::Stored {
value, attributes, ..
} => {
if !attributes.contains(ReadOnly) {
if !attributes.contains(Attribute::READ_ONLY) {
*value = new_value.into();
}
@ -246,20 +246,27 @@ impl<'gc> Property<'gc> {
}
pub fn can_delete(&self) -> bool {
match self {
Property::Virtual { attributes, .. } => !attributes.contains(DontDelete),
Property::Stored { attributes, .. } => !attributes.contains(DontDelete),
Property::Slot { attributes, .. } => !attributes.contains(DontDelete),
}
let attributes = match self {
Property::Virtual { attributes, .. } => attributes,
Property::Stored { attributes, .. } => attributes,
Property::Slot { attributes, .. } => attributes,
};
!attributes.contains(Attribute::DONT_DELETE)
}
pub fn is_overwritable(&self) -> bool {
match self {
let attributes = match self {
Property::Virtual {
attributes, set, ..
} => !attributes.contains(ReadOnly) && !set.is_none(),
Property::Stored { attributes, .. } => !attributes.contains(ReadOnly),
Property::Slot { attributes, .. } => !attributes.contains(ReadOnly),
}
} => {
if set.is_none() {
return false;
}
attributes
}
Property::Stored { attributes, .. } => attributes,
Property::Slot { attributes, .. } => attributes,
};
!attributes.contains(Attribute::READ_ONLY)
}
}

View File

@ -3,7 +3,6 @@
use crate::avm2::property::Attribute;
use crate::avm2::value::Value;
use crate::avm2::Error;
use enumset::EnumSet;
use gc_arena::{Collect, CollectionContext};
/// Represents a single slot on an object.
@ -20,7 +19,7 @@ pub enum Slot<'gc> {
/// TODO: For some reason, rustc believes this variant is unused.
Occupied {
value: Value<'gc>,
attributes: EnumSet<Attribute>,
attributes: Attribute,
},
}
@ -44,7 +43,7 @@ impl<'gc> Slot<'gc> {
pub fn new(value: impl Into<Value<'gc>>) -> Self {
Self::Occupied {
value: value.into(),
attributes: EnumSet::empty(),
attributes: Attribute::empty(),
}
}
@ -52,7 +51,7 @@ impl<'gc> Slot<'gc> {
pub fn new_const(value: impl Into<Value<'gc>>) -> Self {
Self::Occupied {
value: value.into(),
attributes: EnumSet::from(Attribute::ReadOnly),
attributes: Attribute::READ_ONLY,
}
}
@ -69,7 +68,7 @@ impl<'gc> Slot<'gc> {
match self {
Self::Unoccupied => Err("Cannot overwrite unoccupied slot".into()),
Self::Occupied { value, attributes } => {
if attributes.contains(Attribute::ReadOnly) {
if attributes.contains(Attribute::READ_ONLY) {
return Err("Cannot overwrite const slot".into());
}

View File

@ -7,20 +7,21 @@ use crate::avm2::script::TranslationUnit;
use crate::avm2::value::{abc_default_value, Value};
use crate::avm2::{Avm2, Error};
use crate::collect::CollectWrapper;
use enumset::{EnumSet, EnumSetType};
use bitflags::bitflags;
use gc_arena::{Collect, GcCell, MutationContext};
use swf::avm2::types::{Trait as AbcTrait, TraitKind as AbcTraitKind};
/// All attributes a trait can have.
#[derive(Debug, EnumSetType)]
pub enum TraitAttributes {
/// Whether or not traits in downstream classes are allowed to override
/// this trait.
Final,
bitflags! {
/// All attributes a trait can have.
pub struct TraitAttributes: u8 {
/// Whether or not traits in downstream classes are allowed to override
/// this trait.
const FINAL = 1 << 0;
/// Whether or not this trait is intended to override an upstream class's
/// trait.
Override,
/// Whether or not this trait is intended to override an upstream class's
/// trait.
const OVERRIDE = 1 << 1;
}
}
/// Represents a trait as loaded into the VM.
@ -40,19 +41,17 @@ pub struct Trait<'gc> {
name: QName<'gc>,
/// The attributes set on this trait.
attributes: CollectWrapper<EnumSet<TraitAttributes>>,
attributes: CollectWrapper<TraitAttributes>,
/// The kind of trait in use.
kind: TraitKind<'gc>,
}
fn trait_attribs_from_abc_traits(abc_trait: &AbcTrait) -> CollectWrapper<EnumSet<TraitAttributes>> {
CollectWrapper(match (abc_trait.is_final, abc_trait.is_override) {
(true, true) => TraitAttributes::Final | TraitAttributes::Override,
(true, false) => TraitAttributes::Final.into(),
(false, true) => TraitAttributes::Override.into(),
(false, false) => EnumSet::empty(),
})
fn trait_attribs_from_abc_traits(abc_trait: &AbcTrait) -> CollectWrapper<TraitAttributes> {
let mut attributes = TraitAttributes::empty();
attributes.set(TraitAttributes::FINAL, abc_trait.is_final);
attributes.set(TraitAttributes::OVERRIDE, abc_trait.is_override);
CollectWrapper(attributes)
}
/// The fields for a particular kind of trait.
@ -104,7 +103,7 @@ impl<'gc> Trait<'gc> {
Trait {
name,
attributes: CollectWrapper(EnumSet::empty()),
attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Class { slot_id: 0, class },
}
}
@ -112,7 +111,7 @@ impl<'gc> Trait<'gc> {
pub fn from_method(name: QName<'gc>, method: Method<'gc>) -> Self {
Trait {
name,
attributes: CollectWrapper(EnumSet::empty()),
attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Method { disp_id: 0, method },
}
}
@ -120,7 +119,7 @@ impl<'gc> Trait<'gc> {
pub fn from_getter(name: QName<'gc>, method: Method<'gc>) -> Self {
Trait {
name,
attributes: CollectWrapper(EnumSet::empty()),
attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Getter { disp_id: 0, method },
}
}
@ -128,7 +127,7 @@ impl<'gc> Trait<'gc> {
pub fn from_setter(name: QName<'gc>, method: Method<'gc>) -> Self {
Trait {
name,
attributes: CollectWrapper(EnumSet::empty()),
attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Setter { disp_id: 0, method },
}
}
@ -136,7 +135,7 @@ impl<'gc> Trait<'gc> {
pub fn from_function(name: QName<'gc>, function: Method<'gc>) -> Self {
Trait {
name,
attributes: CollectWrapper(EnumSet::empty()),
attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Function {
slot_id: 0,
function,
@ -151,7 +150,7 @@ impl<'gc> Trait<'gc> {
) -> Self {
Trait {
name,
attributes: CollectWrapper(EnumSet::empty()),
attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Slot {
slot_id: 0,
type_name,
@ -167,7 +166,7 @@ impl<'gc> Trait<'gc> {
) -> Self {
Trait {
name,
attributes: CollectWrapper(EnumSet::empty()),
attributes: CollectWrapper(TraitAttributes::empty()),
kind: TraitKind::Slot {
slot_id: 0,
type_name,
@ -280,14 +279,14 @@ impl<'gc> Trait<'gc> {
}
pub fn is_final(&self) -> bool {
self.attributes.0.contains(TraitAttributes::Final)
self.attributes.0.contains(TraitAttributes::FINAL)
}
pub fn is_override(&self) -> bool {
self.attributes.0.contains(TraitAttributes::Override)
self.attributes.0.contains(TraitAttributes::OVERRIDE)
}
pub fn set_attributes(&mut self, attribs: EnumSet<TraitAttributes>) {
pub fn set_attributes(&mut self, attribs: TraitAttributes) {
self.attributes.0 = attribs;
}

View File

@ -8,7 +8,6 @@ use crate::avm2::script::TranslationUnit;
use crate::avm2::string::AvmString;
use crate::avm2::{Avm2, Error};
use crate::ecma_conversions::{f64_to_wrapping_i32, f64_to_wrapping_u32};
use enumset::{EnumSet, EnumSetType};
use gc_arena::{Collect, MutationContext};
use std::cell::Ref;
use std::f64::NAN;
@ -446,20 +445,6 @@ impl<'gc> Value<'gc> {
Ok(f64_to_wrapping_i32(self.coerce_to_number(activation)?))
}
/// Coerce the value to an EnumSet of a particular type.
///
/// This function will ignore invalid bits of the value when interpreting
/// the enum.
pub fn coerce_to_enumset<E>(
&self,
activation: &mut Activation<'_, 'gc, '_>,
) -> Result<EnumSet<E>, Error>
where
E: EnumSetType,
{
Ok(EnumSet::from_u32_truncated(self.coerce_to_u32(activation)?))
}
/// Minimum number of digits after which numbers are formatted as
/// exponential strings.
const MIN_DIGITS: f64 = -6.0;

View File

@ -9,7 +9,7 @@ use crate::tag_utils::SwfMovie;
use crate::transform::Transform;
use crate::types::{Degrees, Percent};
use crate::vminterface::Instantiator;
use enumset::{EnumSet, EnumSetType};
use bitflags::bitflags;
use gc_arena::{Collect, MutationContext};
use ruffle_macros::enum_trait_object;
use std::cell::{Ref, RefMut};
@ -68,7 +68,7 @@ pub struct DisplayObjectBase<'gc> {
next_sibling: Option<DisplayObject<'gc>>,
/// Bit flags for various display object properites.
flags: EnumSet<DisplayObjectFlags>,
flags: DisplayObjectFlags,
}
impl<'gc> Default for DisplayObjectBase<'gc> {
@ -86,7 +86,7 @@ impl<'gc> Default for DisplayObjectBase<'gc> {
skew: 0.0,
prev_sibling: None,
next_sibling: None,
flags: DisplayObjectFlags::Visible.into(),
flags: DisplayObjectFlags::VISIBLE,
}
}
}
@ -104,28 +104,30 @@ unsafe impl<'gc> Collect for DisplayObjectBase<'gc> {
impl<'gc> DisplayObjectBase<'gc> {
/// Reset all properties that would be adjusted by a movie load.
fn reset_for_movie_load(&mut self) {
let flags_to_keep = self
.flags
.intersection(EnumSet::from(DisplayObjectFlags::LockRoot));
self.flags = DisplayObjectFlags::Visible.into();
self.flags.insert_all(flags_to_keep);
let flags_to_keep = self.flags & DisplayObjectFlags::LOCK_ROOT;
self.flags = flags_to_keep | DisplayObjectFlags::VISIBLE;
}
fn id(&self) -> CharacterId {
0
}
fn depth(&self) -> Depth {
self.depth
}
fn set_depth(&mut self, depth: Depth) {
self.depth = depth;
}
fn place_frame(&self) -> u16 {
self.place_frame
}
fn set_place_frame(&mut self, _context: MutationContext<'gc, '_>, frame: u16) {
self.place_frame = frame;
}
fn transform(&self) -> &Transform {
&self.transform
}
@ -133,19 +135,24 @@ impl<'gc> DisplayObjectBase<'gc> {
fn matrix(&self) -> &Matrix {
&self.transform.matrix
}
fn matrix_mut(&mut self, _context: MutationContext<'gc, '_>) -> &mut Matrix {
&mut self.transform.matrix
}
fn set_matrix(&mut self, _context: MutationContext<'gc, '_>, matrix: &Matrix) {
self.transform.matrix = *matrix;
self.flags.remove(DisplayObjectFlags::ScaleRotationCached);
self.flags -= DisplayObjectFlags::SCALE_ROTATION_CACHED;
}
fn color_transform(&self) -> &ColorTransform {
&self.transform.color_transform
}
fn color_transform_mut(&mut self) -> &mut ColorTransform {
&mut self.transform.color_transform
}
fn set_color_transform(
&mut self,
_context: MutationContext<'gc, '_>,
@ -153,16 +160,20 @@ impl<'gc> DisplayObjectBase<'gc> {
) {
self.transform.color_transform = *color_transform;
}
fn x(&self) -> f64 {
self.transform.matrix.tx.to_pixels()
}
fn set_x(&mut self, value: f64) {
self.set_transformed_by_script(true);
self.transform.matrix.tx = Twips::from_pixels(value)
}
fn y(&self) -> f64 {
self.transform.matrix.ty.to_pixels()
}
fn set_y(&mut self, value: f64) {
self.set_transformed_by_script(true);
self.transform.matrix.ty = Twips::from_pixels(value)
@ -172,7 +183,10 @@ impl<'gc> DisplayObjectBase<'gc> {
/// Calculating these requires heavy trig ops, so we only do it when `_xscale`, `_yscale` or
/// `_rotation` is accessed.
fn cache_scale_rotation(&mut self) {
if !self.flags.contains(DisplayObjectFlags::ScaleRotationCached) {
if !self
.flags
.contains(DisplayObjectFlags::SCALE_ROTATION_CACHED)
{
let (a, b, c, d) = (
f64::from(self.transform.matrix.a),
f64::from(self.transform.matrix.b),
@ -201,7 +215,7 @@ impl<'gc> DisplayObjectBase<'gc> {
self.scale_x = Percent::from_unit(scale_x);
self.scale_y = Percent::from_unit(scale_y);
self.skew = rotation_y - rotation_x;
self.flags.insert(DisplayObjectFlags::ScaleRotationCached);
self.flags |= DisplayObjectFlags::SCALE_ROTATION_CACHED;
}
}
@ -224,6 +238,7 @@ impl<'gc> DisplayObjectBase<'gc> {
self.cache_scale_rotation();
self.rotation
}
fn set_rotation(&mut self, degrees: Degrees) {
self.set_transformed_by_script(true);
self.cache_scale_rotation();
@ -238,10 +253,12 @@ impl<'gc> DisplayObjectBase<'gc> {
matrix.c = (self.scale_y.into_unit() * -sin_y) as f32;
matrix.d = (self.scale_y.into_unit() * cos_y) as f32;
}
fn scale_x(&mut self) -> Percent {
self.cache_scale_rotation();
self.scale_x
}
fn set_scale_x(&mut self, value: Percent) {
self.set_transformed_by_script(true);
self.cache_scale_rotation();
@ -252,10 +269,12 @@ impl<'gc> DisplayObjectBase<'gc> {
matrix.a = (cos * value.into_unit()) as f32;
matrix.b = (sin * value.into_unit()) as f32;
}
fn scale_y(&mut self) -> Percent {
self.cache_scale_rotation();
self.scale_y
}
fn set_scale_y(&mut self, value: Percent) {
self.set_transformed_by_script(true);
self.cache_scale_rotation();
@ -270,25 +289,32 @@ impl<'gc> DisplayObjectBase<'gc> {
fn name(&self) -> &str {
&self.name
}
fn set_name(&mut self, _context: MutationContext<'gc, '_>, name: &str) {
self.name = name.to_string();
}
fn alpha(&self) -> f64 {
f64::from(self.color_transform().a_mult)
}
fn set_alpha(&mut self, value: f64) {
self.set_transformed_by_script(true);
self.color_transform_mut().a_mult = value as f32
}
fn clip_depth(&self) -> Depth {
self.clip_depth
}
fn set_clip_depth(&mut self, _context: MutationContext<'gc, '_>, depth: Depth) {
self.clip_depth = depth;
}
fn parent(&self) -> Option<DisplayObject<'gc>> {
self.parent
}
fn set_parent(
&mut self,
_context: MutationContext<'gc, '_>,
@ -296,9 +322,11 @@ impl<'gc> DisplayObjectBase<'gc> {
) {
self.parent = parent;
}
fn prev_sibling(&self) -> Option<DisplayObject<'gc>> {
self.prev_sibling
}
fn set_prev_sibling(
&mut self,
_context: MutationContext<'gc, '_>,
@ -306,9 +334,11 @@ impl<'gc> DisplayObjectBase<'gc> {
) {
self.prev_sibling = node;
}
fn next_sibling(&self) -> Option<DisplayObject<'gc>> {
self.next_sibling
}
fn set_next_sibling(
&mut self,
_context: MutationContext<'gc, '_>,
@ -316,77 +346,78 @@ impl<'gc> DisplayObjectBase<'gc> {
) {
self.next_sibling = node;
}
fn removed(&self) -> bool {
self.flags.contains(DisplayObjectFlags::Removed)
self.flags.contains(DisplayObjectFlags::REMOVED)
}
fn set_removed(&mut self, value: bool) {
if value {
self.flags.insert(DisplayObjectFlags::Removed);
self.flags |= DisplayObjectFlags::REMOVED;
} else {
self.flags.remove(DisplayObjectFlags::Removed);
self.flags -= DisplayObjectFlags::REMOVED;
}
}
fn visible(&self) -> bool {
self.flags.contains(DisplayObjectFlags::Visible)
self.flags.contains(DisplayObjectFlags::VISIBLE)
}
fn set_visible(&mut self, value: bool) {
if value {
self.flags.insert(DisplayObjectFlags::Visible);
self.flags |= DisplayObjectFlags::VISIBLE;
} else {
self.flags.remove(DisplayObjectFlags::Visible);
self.flags -= DisplayObjectFlags::VISIBLE;
}
}
fn lock_root(&self) -> bool {
self.flags.contains(DisplayObjectFlags::LockRoot)
self.flags.contains(DisplayObjectFlags::LOCK_ROOT)
}
fn set_lock_root(&mut self, value: bool) {
if value {
self.flags.insert(DisplayObjectFlags::LockRoot);
self.flags |= DisplayObjectFlags::LOCK_ROOT;
} else {
self.flags.remove(DisplayObjectFlags::LockRoot);
self.flags -= DisplayObjectFlags::LOCK_ROOT;
}
}
fn transformed_by_script(&self) -> bool {
self.flags.contains(DisplayObjectFlags::TransformedByScript)
self.flags
.contains(DisplayObjectFlags::TRANSFORMED_BY_SCRIPT)
}
fn set_transformed_by_script(&mut self, value: bool) {
if value {
self.flags.insert(DisplayObjectFlags::TransformedByScript);
self.flags |= DisplayObjectFlags::TRANSFORMED_BY_SCRIPT;
} else {
self.flags.remove(DisplayObjectFlags::TransformedByScript);
self.flags -= DisplayObjectFlags::TRANSFORMED_BY_SCRIPT;
}
}
fn placed_by_script(&self) -> bool {
self.flags.contains(DisplayObjectFlags::PlacedByScript)
self.flags.contains(DisplayObjectFlags::PLACED_BY_SCRIPT)
}
fn set_placed_by_script(&mut self, value: bool) {
if value {
self.flags.insert(DisplayObjectFlags::PlacedByScript);
self.flags |= DisplayObjectFlags::PLACED_BY_SCRIPT;
} else {
self.flags.remove(DisplayObjectFlags::PlacedByScript);
self.flags -= DisplayObjectFlags::PLACED_BY_SCRIPT;
}
}
fn instantiated_by_timeline(&self) -> bool {
self.flags
.contains(DisplayObjectFlags::InstantiatedByTimeline)
.contains(DisplayObjectFlags::INSTANTIATED_BY_TIMELINE)
}
fn set_instantiated_by_timeline(&mut self, value: bool) {
if value {
self.flags
.insert(DisplayObjectFlags::InstantiatedByTimeline);
self.flags |= DisplayObjectFlags::INSTANTIATED_BY_TIMELINE;
} else {
self.flags
.remove(DisplayObjectFlags::InstantiatedByTimeline);
self.flags -= DisplayObjectFlags::INSTANTIATED_BY_TIMELINE;
}
}
@ -1268,33 +1299,35 @@ impl<'gc> DisplayObject<'gc> {
}
}
/// Bit flags used by `DisplayObject`.
#[derive(Collect, EnumSetType, Debug)]
#[collect(no_drop)]
enum DisplayObjectFlags {
/// Whether this object has been removed from the display list.
/// Necessary in AVM1 to throw away queued actions from removed movie clips.
Removed,
bitflags! {
/// Bit flags used by `DisplayObject`.
#[derive(Collect)]
#[collect(no_drop)]
struct DisplayObjectFlags: u8 {
/// Whether this object has been removed from the display list.
/// Necessary in AVM1 to throw away queued actions from removed movie clips.
const REMOVED = 1 << 0;
/// If this object is visible (`_visible` property).
Visible,
/// If this object is visible (`_visible` property).
const VISIBLE = 1 << 1;
/// Whether the `_xscale`, `_yscale` and `_rotation` of the object have been calculated and cached.
ScaleRotationCached,
/// Whether the `_xscale`, `_yscale` and `_rotation` of the object have been calculated and cached.
const SCALE_ROTATION_CACHED = 1 << 2;
/// Whether this object has been transformed by ActionScript.
/// When this flag is set, changes from SWF `PlaceObject` tags are ignored.
TransformedByScript,
/// Whether this object has been transformed by ActionScript.
/// When this flag is set, changes from SWF `PlaceObject` tags are ignored.
const TRANSFORMED_BY_SCRIPT = 1 << 3;
/// Whether this object has been placed in a container by ActionScript 3.
/// When this flag is set, changes from SWF `RemoveObject` tags are ignored.
PlacedByScript,
/// Whether this object has been placed in a container by ActionScript 3.
/// When this flag is set, changes from SWF `RemoveObject` tags are ignored.
const PLACED_BY_SCRIPT = 1 << 4;
/// Whether this object has been instantiated by a SWF tag.
/// When this flag is set, changes from SWF `RemoveObject` tags are ignored.
InstantiatedByTimeline,
/// Whether this object has been instantiated by a SWF tag.
/// When this flag is set, changes from SWF `RemoveObject` tags are ignored.
const INSTANTIATED_BY_TIMELINE = 1 << 5;
/// Whether this object has `_lockroot` set to true, in which case
/// it becomes the _root of itself and of any children
LockRoot,
/// Whether this object has `_lockroot` set to true, in which case
/// it becomes the _root of itself and of any children
const LOCK_ROOT = 1 << 6;
}
}

View File

@ -181,7 +181,7 @@ impl<'gc> Button<'gc> {
// Kill children that no longer exist in this state.
for depth in removed_depths {
if let Some(child) = self.child_by_depth(depth) {
self.remove_child(context, child, EnumSet::all());
self.remove_child(context, child, Lists::all());
}
}

View File

@ -5,7 +5,7 @@ use crate::display_object::button::Button;
use crate::display_object::movie_clip::MovieClip;
use crate::display_object::{Depth, DisplayObject, TDisplayObject};
use crate::string_utils::swf_string_eq_ignore_case;
use enumset::{EnumSet, EnumSetType};
use bitflags::bitflags;
use gc_arena::{Collect, MutationContext};
use ruffle_macros::enum_trait_object;
use std::cmp::Ordering;
@ -13,24 +13,25 @@ use std::collections::BTreeMap;
use std::fmt::Debug;
use std::ops::RangeBounds;
/// The three lists that a display object container is supposed to maintain.
#[derive(EnumSetType)]
pub enum Lists {
/// The list that determines the order in which children are rendered.
///
/// This is directly manipulated by AVM2 code.
Render,
bitflags! {
/// The three lists that a display object container is supposed to maintain.
pub struct Lists: u8 {
/// The list that determines the order in which children are rendered.
///
/// This is directly manipulated by AVM2 code.
const RENDER = 1 << 0;
/// The list that determines the identity of children according to the
/// timeline and AVM1 code.
///
/// Manipulations of the depth list are generally propagated to the render
/// list, except in cases where children have been reordered by AVM2.
Depth,
/// The list that determines the identity of children according to the
/// timeline and AVM1 code.
///
/// Manipulations of the depth list are generally propagated to the render
/// list, except in cases where children have been reordered by AVM2.
const DEPTH = 1 << 1;
/// The list that determines the order in which childrens' actions are
/// executed.
Execution,
/// The list that determines the order in which childrens' actions are
/// executed.
const EXECUTION = 1 << 2;
}
}
#[enum_trait_object(
@ -149,7 +150,7 @@ pub trait TDisplayObjectContainer<'gc>:
&mut self,
context: &mut UpdateContext<'_, 'gc, '_>,
child: DisplayObject<'gc>,
from_lists: EnumSet<Lists>,
from_lists: Lists,
) -> bool;
/// Remove a set of children identified by their render list indicies from
@ -365,7 +366,7 @@ macro_rules! impl_display_object_container {
if let Some(old_parent) = child.parent() {
if !DisplayObject::ptr_eq(old_parent, (*self).into()) {
if let Some(mut old_parent) = old_parent.as_container() {
old_parent.remove_child(context, child, EnumSet::all());
old_parent.remove_child(context, child, Lists::all());
}
}
}
@ -395,7 +396,7 @@ macro_rules! impl_display_object_container {
&mut self,
context: &mut UpdateContext<'_, 'gc, '_>,
child: DisplayObject<'gc>,
from_lists: EnumSet<Lists>,
from_lists: Lists,
) -> bool {
debug_assert!(DisplayObject::ptr_eq(
child.parent().unwrap(),
@ -404,11 +405,11 @@ macro_rules! impl_display_object_container {
let mut write = self.0.write(context.gc_context);
let removed_from_depth_list = from_lists.contains(Lists::Depth)
let removed_from_depth_list = from_lists.contains(Lists::DEPTH)
&& write.$field.remove_child_from_depth_list(child);
let removed_from_render_list = from_lists.contains(Lists::Render)
let removed_from_render_list = from_lists.contains(Lists::RENDER)
&& write.$field.remove_child_from_render_list(child);
let removed_from_execution_list = from_lists.contains(Lists::Execution)
let removed_from_execution_list = from_lists.contains(Lists::EXECUTION)
&& write.$field.remove_child_from_exec_list(context, child);
drop(write);

View File

@ -8,6 +8,7 @@ use crate::avm2::{
StageObject as Avm2StageObject, TObject as Avm2TObject, Value as Avm2Value,
};
use crate::backend::audio::AudioStreamHandle;
use bitflags::bitflags;
use crate::avm1::activation::{Activation as Avm1Activation, ActivationIdentifier};
use crate::character::Character;
@ -24,7 +25,6 @@ use crate::shape_utils::DrawCommand;
use crate::tag_utils::{self, DecodeResult, SwfMovie, SwfSlice, SwfStream};
use crate::types::{Degrees, Percent};
use crate::vminterface::{AvmObject, AvmType, Instantiator};
use enumset::{EnumSet, EnumSetType};
use gc_arena::{Collect, Gc, GcCell, MutationContext};
use smallvec::SmallVec;
use std::cell::{Ref, RefCell};
@ -57,7 +57,7 @@ pub struct MovieClipData<'gc> {
clip_actions: Vec<ClipAction>,
frame_scripts: Vec<Avm2FrameScript<'gc>>,
has_button_clip_event: bool,
flags: EnumSet<MovieClipFlags>,
flags: MovieClipFlags,
avm2_constructor: Option<Avm2Object<'gc>>,
drawing: Drawing,
is_focusable: bool,
@ -93,7 +93,7 @@ impl<'gc> MovieClip<'gc> {
clip_actions: Vec::new(),
frame_scripts: Vec::new(),
has_button_clip_event: false,
flags: EnumSet::empty(),
flags: MovieClipFlags::empty(),
avm2_constructor: None,
drawing: Drawing::new(),
is_focusable: false,
@ -125,7 +125,7 @@ impl<'gc> MovieClip<'gc> {
clip_actions: Vec::new(),
frame_scripts: Vec::new(),
has_button_clip_event: false,
flags: MovieClipFlags::Playing.into(),
flags: MovieClipFlags::PLAYING,
avm2_constructor: None,
drawing: Drawing::new(),
is_focusable: false,
@ -1159,9 +1159,9 @@ impl<'gc> MovieClip<'gc> {
.collect();
for (_depth, child) in children {
if !child.placed_by_script() {
self.remove_child(context, child, EnumSet::all());
self.remove_child(context, child, Lists::all());
} else {
self.remove_child(context, child, Lists::Depth.into());
self.remove_child(context, child, Lists::DEPTH);
}
}
true
@ -1533,10 +1533,10 @@ impl<'gc> MovieClip<'gc> {
if let Some(child) = read.container.get_depth(depth) {
if !child.placed_by_script() {
drop(read);
self.remove_child(context, child, EnumSet::all());
self.remove_child(context, child, Lists::all());
} else {
drop(read);
self.remove_child(context, child, Lists::Depth.into());
self.remove_child(context, child, Lists::DEPTH);
}
}
}
@ -1826,7 +1826,7 @@ impl<'gc> MovieClipData<'gc> {
MovieClipStatic::with_data(0, movie.into(), total_frames),
);
self.tag_stream_pos = 0;
self.flags = MovieClipFlags::Playing.into();
self.flags = MovieClipFlags::PLAYING;
self.current_frame = 0;
self.audio_stream = None;
self.container = ChildContainer::new();
@ -1845,23 +1845,23 @@ impl<'gc> MovieClipData<'gc> {
}
fn playing(&self) -> bool {
self.flags.contains(MovieClipFlags::Playing)
self.flags.contains(MovieClipFlags::PLAYING)
}
fn set_playing(&mut self, value: bool) {
if value {
self.flags.insert(MovieClipFlags::Playing);
self.flags |= MovieClipFlags::PLAYING;
} else {
self.flags.remove(MovieClipFlags::Playing);
self.flags -= MovieClipFlags::PLAYING;
}
}
fn programmatically_played(&self) -> bool {
self.flags.contains(MovieClipFlags::ProgrammaticallyPlayed)
self.flags.contains(MovieClipFlags::PROGRAMMATICALLY_PLAYED)
}
fn set_programmatically_played(&mut self) {
self.flags.insert(MovieClipFlags::ProgrammaticallyPlayed);
self.flags |= MovieClipFlags::PROGRAMMATICALLY_PLAYED;
}
fn play(&mut self) {
@ -2000,15 +2000,17 @@ impl<'gc> MovieClipData<'gc> {
}
fn initialized(&self) -> bool {
self.flags.contains(MovieClipFlags::Initialized)
self.flags.contains(MovieClipFlags::INITIALIZED)
}
fn set_initialized(&mut self, value: bool) -> bool {
let ret = self.flags.contains(MovieClipFlags::INITIALIZED);
if value {
self.flags.insert(MovieClipFlags::Initialized)
self.flags |= MovieClipFlags::INITIALIZED;
} else {
self.flags.remove(MovieClipFlags::Initialized)
self.flags -= MovieClipFlags::INITIALIZED;
}
!ret
}
/// Stops the audio stream if one is playing.
@ -2808,9 +2810,9 @@ impl<'gc, 'a> MovieClip<'gc> {
if let Some(child) = self.child_by_depth(remove_object.depth.into()) {
if !child.placed_by_script() {
self.remove_child(context, child, EnumSet::all());
self.remove_child(context, child, Lists::all());
} else {
self.remove_child(context, child, Lists::Depth.into());
self.remove_child(context, child, Lists::DEPTH);
}
}
@ -3061,20 +3063,21 @@ impl<'a> GotoPlaceObject<'a> {
}
}
/// Boolean state flags used by `MovieClip`.
#[derive(Debug, EnumSetType)]
enum MovieClipFlags {
/// Whether this `MovieClip` has run its initial frame.
Initialized,
bitflags! {
/// Boolean state flags used by `MovieClip`.
struct MovieClipFlags: u8 {
/// Whether this `MovieClip` has run its initial frame.
const INITIALIZED = 1 << 0;
/// Whether this `MovieClip` is playing or stopped.
Playing,
/// Whether this `MovieClip` is playing or stopped.
const PLAYING = 1 << 1;
/// Whether this `MovieClip` has been played as a result of an AS3 command.
///
/// The AS3 `isPlaying` property is broken and yields false until you first
/// call `play` to unbreak it. This flag tracks that bug.
ProgrammaticallyPlayed,
/// Whether this `MovieClip` has been played as a result of an AS3 command.
///
/// The AS3 `isPlaying` property is broken and yields false until you first
/// call `play` to unbreak it. This flag tracks that bug.
const PROGRAMMATICALLY_PLAYED = 1 << 2;
}
}
/// Actions that are attached to a `MovieClip` event in
@ -3105,31 +3108,42 @@ impl ClipAction {
let action_data = SwfSlice::from(movie)
.to_unbounded_subslice(other.action_data)
.unwrap();
other.events.into_iter().map(move |event| Self {
let mut events = Vec::new();
let flags = other.events.bits();
let mut bit = 1u32;
while flags & !(bit - 1) != 0 {
if (flags & bit) != 0 {
events.push(ClipEventFlag::from_bits_truncate(bit));
}
bit <<= 1;
}
events.into_iter().map(move |event| Self {
event: match event {
ClipEventFlag::Construct => ClipEvent::Construct,
ClipEventFlag::Data => ClipEvent::Data,
ClipEventFlag::DragOut => ClipEvent::DragOut,
ClipEventFlag::DragOver => ClipEvent::DragOver,
ClipEventFlag::EnterFrame => ClipEvent::EnterFrame,
ClipEventFlag::Initialize => ClipEvent::Initialize,
ClipEventFlag::KeyUp => ClipEvent::KeyUp,
ClipEventFlag::KeyDown => ClipEvent::KeyDown,
ClipEventFlag::KeyPress => ClipEvent::KeyPress {
ClipEventFlag::CONSTRUCT => ClipEvent::Construct,
ClipEventFlag::DATA => ClipEvent::Data,
ClipEventFlag::DRAG_OUT => ClipEvent::DragOut,
ClipEventFlag::DRAG_OVER => ClipEvent::DragOver,
ClipEventFlag::ENTER_FRAME => ClipEvent::EnterFrame,
ClipEventFlag::INITIALIZE => ClipEvent::Initialize,
ClipEventFlag::KEY_UP => ClipEvent::KeyUp,
ClipEventFlag::KEY_DOWN => ClipEvent::KeyDown,
ClipEventFlag::KEY_PRESS => ClipEvent::KeyPress {
key_code: key_code
.and_then(|k| ButtonKeyCode::try_from(k).ok())
.unwrap_or(ButtonKeyCode::Unknown),
},
ClipEventFlag::Load => ClipEvent::Load,
ClipEventFlag::MouseUp => ClipEvent::MouseUp,
ClipEventFlag::MouseDown => ClipEvent::MouseDown,
ClipEventFlag::MouseMove => ClipEvent::MouseMove,
ClipEventFlag::Press => ClipEvent::Press,
ClipEventFlag::RollOut => ClipEvent::RollOut,
ClipEventFlag::RollOver => ClipEvent::RollOver,
ClipEventFlag::Release => ClipEvent::Release,
ClipEventFlag::ReleaseOutside => ClipEvent::ReleaseOutside,
ClipEventFlag::Unload => ClipEvent::Unload,
ClipEventFlag::LOAD => ClipEvent::Load,
ClipEventFlag::MOUSE_UP => ClipEvent::MouseUp,
ClipEventFlag::MOUSE_DOWN => ClipEvent::MouseDown,
ClipEventFlag::MOUSE_MOVE => ClipEvent::MouseMove,
ClipEventFlag::PRESS => ClipEvent::Press,
ClipEventFlag::ROLL_OUT => ClipEvent::RollOut,
ClipEventFlag::ROLL_OVER => ClipEvent::RollOver,
ClipEventFlag::RELEASE => ClipEvent::Release,
ClipEventFlag::RELEASE_OUTSIDE => ClipEvent::ReleaseOutside,
ClipEventFlag::UNLOAD => ClipEvent::Unload,
_ => unreachable!(),
},
action_data: action_data.clone(),
})

View File

@ -2,6 +2,7 @@ use crate::avm1::activation::{Activation, ActivationIdentifier};
use crate::avm1::debug::VariableDumper;
use crate::avm1::globals::system::SystemProperties;
use crate::avm1::object::Object;
use crate::avm1::property::Attribute;
use crate::avm1::{Avm1, AvmString, ScriptObject, TObject, Timers, Value};
use crate::avm2::{Avm2, Domain as Avm2Domain};
use crate::backend::input::{InputBackend, MouseCursor};
@ -23,7 +24,6 @@ use crate::property_map::PropertyMap;
use crate::tag_utils::SwfMovie;
use crate::transform::TransformStack;
use crate::vminterface::{AvmType, Instantiator};
use enumset::EnumSet;
use gc_arena::{make_arena, ArenaParameters, Collect, GcCell};
use instant::Instant;
use log::info;
@ -388,7 +388,7 @@ impl Player {
context.gc_context,
key,
AvmString::new(context.gc_context, value).into(),
EnumSet::empty(),
Attribute::empty(),
);
}
Some(object.into())
@ -426,7 +426,7 @@ impl Player {
activation.context.gc_context,
"$version",
AvmString::new(activation.context.gc_context, version_string).into(),
EnumSet::empty(),
Attribute::empty(),
);
});

View File

@ -7,7 +7,6 @@ pub use crate::display_object::{
pub use crate::{
impl_display_object, impl_display_object_container, impl_display_object_sansbounds,
};
pub use enumset::EnumSet;
pub use log::{error, info, trace, warn};
pub use std::ops::{Bound, RangeBounds};
pub use swf::Matrix;

View File

@ -10,10 +10,10 @@ readme = "README.md"
description = "Read and write the Adobe Flash SWF file format."
[dependencies]
bitflags = "1.2.1"
bitstream-io = "1.0.0"
byteorder = "1.4"
encoding_rs = "0.8.26"
enumset = "1.0.1"
num-derive = "0.3"
num-traits = "0.2"
libflate = {version = "1.0", optional = true}

View File

@ -13,7 +13,6 @@ use crate::{
};
use bitstream_io::BitRead;
use byteorder::{LittleEndian, ReadBytesExt};
use enumset::EnumSet;
use std::collections::HashSet;
use std::io::{self, Read};
@ -2198,7 +2197,7 @@ impl<'a> Reader<'a> {
Ok(None)
} else {
let mut length = self.read_u32()?;
let key_code = if events.contains(ClipEventFlag::KeyPress) {
let key_code = if events.contains(ClipEventFlag::KEY_PRESS) {
// ActionData length includes the 1 byte key code.
length -= 1;
Some(self.read_u8()?)
@ -2215,83 +2214,46 @@ impl<'a> Reader<'a> {
}
}
fn read_clip_event_flags(&mut self) -> Result<EnumSet<ClipEventFlag>> {
fn read_clip_event_flags(&mut self) -> Result<ClipEventFlag> {
// TODO: Switch to a bitset.
let mut event_list = EnumSet::new();
let mut event_list = ClipEventFlag::empty();
let flags = self.read_u8()?;
if flags & 0b1000_0000 != 0 {
event_list.insert(ClipEventFlag::KeyUp);
}
if flags & 0b0100_0000 != 0 {
event_list.insert(ClipEventFlag::KeyDown);
}
if flags & 0b0010_0000 != 0 {
event_list.insert(ClipEventFlag::MouseUp);
}
if flags & 0b0001_0000 != 0 {
event_list.insert(ClipEventFlag::MouseDown);
}
if flags & 0b0000_1000 != 0 {
event_list.insert(ClipEventFlag::MouseMove);
}
if flags & 0b0000_0100 != 0 {
event_list.insert(ClipEventFlag::Unload);
}
if flags & 0b0000_0010 != 0 {
event_list.insert(ClipEventFlag::EnterFrame);
}
if flags & 0b0000_0001 != 0 {
event_list.insert(ClipEventFlag::Load);
}
if self.version < 6 {
event_list.set(ClipEventFlag::KEY_UP, flags & 0b1000_0000 != 0);
event_list.set(ClipEventFlag::KEY_DOWN, flags & 0b0100_0000 != 0);
event_list.set(ClipEventFlag::MOUSE_UP, flags & 0b0010_0000 != 0);
event_list.set(ClipEventFlag::MOUSE_DOWN, flags & 0b0001_0000 != 0);
event_list.set(ClipEventFlag::MOUSE_MOVE, flags & 0b0000_1000 != 0);
event_list.set(ClipEventFlag::UNLOAD, flags & 0b0000_0100 != 0);
event_list.set(ClipEventFlag::ENTER_FRAME, flags & 0b0000_0010 != 0);
event_list.set(ClipEventFlag::LOAD, flags & 0b0000_0001 != 0);
if self.version > 5 {
let flags = self.read_u8()?;
event_list.set(ClipEventFlag::DRAG_OVER, flags & 0b1000_0000 != 0);
event_list.set(ClipEventFlag::ROLL_OUT, flags & 0b0100_0000 != 0);
event_list.set(ClipEventFlag::ROLL_OVER, flags & 0b0010_0000 != 0);
event_list.set(ClipEventFlag::RELEASE_OUTSIDE, flags & 0b0001_0000 != 0);
event_list.set(ClipEventFlag::RELEASE, flags & 0b0000_1000 != 0);
event_list.set(ClipEventFlag::PRESS, flags & 0b0000_0100 != 0);
event_list.set(ClipEventFlag::INITIALIZE, flags & 0b0000_0010 != 0);
event_list.set(ClipEventFlag::DATA, flags & 0b0000_0001 != 0);
let flags = self.read_u8()?;
// Construct was only added in SWF7, but it's not version-gated;
// Construct events will still fire in SWF6 in a v7+ player. (#1424)
event_list.set(ClipEventFlag::CONSTRUCT, flags & 0b0000_0100 != 0);
event_list.set(ClipEventFlag::KEY_PRESS, flags & 0b0000_0010 != 0);
event_list.set(ClipEventFlag::DRAG_OUT, flags & 0b0000_0001 != 0);
self.read_u8()?;
} else {
// SWF19 pp. 48-50: For SWFv5, the ClipEventFlags only had 2 bytes of flags,
// with the 2nd byte reserved (all 0).
// This was expanded to 4 bytes in SWFv6.
self.read_u8()?;
} else {
let flags = self.read_u8()?;
if flags & 0b1000_0000 != 0 {
event_list.insert(ClipEventFlag::DragOver);
}
if flags & 0b0100_0000 != 0 {
event_list.insert(ClipEventFlag::RollOut);
}
if flags & 0b0010_0000 != 0 {
event_list.insert(ClipEventFlag::RollOver);
}
if flags & 0b0001_0000 != 0 {
event_list.insert(ClipEventFlag::ReleaseOutside);
}
if flags & 0b0000_1000 != 0 {
event_list.insert(ClipEventFlag::Release);
}
if flags & 0b0000_0100 != 0 {
event_list.insert(ClipEventFlag::Press);
}
if flags & 0b0000_0010 != 0 {
event_list.insert(ClipEventFlag::Initialize);
}
if flags & 0b0000_0001 != 0 {
event_list.insert(ClipEventFlag::Data);
}
if self.version < 6 {
self.read_u16()?;
} else {
let flags = self.read_u8()?;
if flags & 0b0000_0100 != 0 {
// Construct was only added in SWF7, but it's not version-gated;
// Construct events will still fire in SWF6 in a v7+ player. (#1424)
event_list.insert(ClipEventFlag::Construct);
}
if flags & 0b0000_0010 != 0 {
event_list.insert(ClipEventFlag::KeyPress);
}
if flags & 0b0000_0001 != 0 {
event_list.insert(ClipEventFlag::DragOut);
}
self.read_u8()?;
}
}
Ok(event_list)
}

View File

@ -2125,7 +2125,7 @@ pub fn tag_tests() -> Vec<TagTestData> {
background_color: None,
blend_mode: None,
clip_actions: Some(vec![ClipAction {
events: ClipEventFlag::EnterFrame.into(),
events: ClipEventFlag::ENTER_FRAME,
key_code: None,
action_data: &[150, 6, 0, 0, 99, 108, 105, 112, 0, 38, 0],
}]),
@ -2156,17 +2156,17 @@ pub fn tag_tests() -> Vec<TagTestData> {
blend_mode: None,
clip_actions: Some(vec![
ClipAction {
events: ClipEventFlag::Press | ClipEventFlag::Release,
events: ClipEventFlag::PRESS | ClipEventFlag::RELEASE,
key_code: None,
action_data: &[150, 3, 0, 0, 65, 0, 38, 0],
},
ClipAction {
events: ClipEventFlag::KeyPress.into(),
events: ClipEventFlag::KEY_PRESS,
key_code: Some(99),
action_data: &[150, 3, 0, 0, 66, 0, 38, 0],
},
ClipAction {
events: ClipEventFlag::EnterFrame.into(),
events: ClipEventFlag::ENTER_FRAME,
key_code: None,
action_data: &[150, 3, 0, 0, 67, 0, 38, 0],
},
@ -2326,12 +2326,12 @@ pub fn tag_tests() -> Vec<TagTestData> {
blend_mode: Some(BlendMode::Difference),
clip_actions: Some(vec![
ClipAction {
events: ClipEventFlag::ReleaseOutside | ClipEventFlag::RollOver,
events: ClipEventFlag::RELEASE_OUTSIDE | ClipEventFlag::ROLL_OVER,
key_code: None,
action_data: &[0],
},
ClipAction {
events: ClipEventFlag::Data.into(),
events: ClipEventFlag::DATA,
key_code: None,
action_data: &[150, 3, 0, 0, 66, 0, 38, 0],
},

View File

@ -4,7 +4,7 @@
//! version 19 (henceforth SWF19):
//! https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf
use crate::string::SwfStr;
use enumset::{EnumSet, EnumSetType};
use bitflags::bitflags;
use std::collections::HashSet;
mod matrix;
@ -418,39 +418,40 @@ pub enum BlendMode {
/// An clip action (a.k.a. clip event) placed on a movieclip instance.
/// Created in the Flash IDE using `onClipEvent` or `on` blocks.
///
/// [SWF19 pp.37-38 ClipActionRecord](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=37)
/// [SWF19 pp.37-38 ClipActionRecord](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=39)
#[derive(Debug, Clone, PartialEq)]
pub struct ClipAction<'a> {
pub events: EnumSet<ClipEventFlag>,
pub events: ClipEventFlag,
pub key_code: Option<KeyCode>,
pub action_data: &'a [u8],
}
/// An event that can be attached to a movieclip instance using
/// an `onClipEvent` or `on` block.
///
/// [SWF19 pp.48-50 ClipEvent](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=38)
#[derive(Debug, EnumSetType)]
pub enum ClipEventFlag {
Construct,
Data,
DragOut,
DragOver,
EnterFrame,
Initialize,
KeyUp,
KeyDown,
KeyPress,
Load,
MouseUp,
MouseDown,
MouseMove,
Press,
RollOut,
RollOver,
Release,
ReleaseOutside,
Unload,
bitflags! {
/// An event that can be attached to a movieclip instance using
/// an `onClipEvent` or `on` block.
///
/// [SWF19 pp.48-50 ClipEvent](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=50)
pub struct ClipEventFlag: u32 {
const CONSTRUCT = 1 << 0;
const DATA = 1 << 1;
const DRAG_OUT = 1 << 2;
const DRAG_OVER = 1 << 3;
const ENTER_FRAME = 1 << 4;
const INITIALIZE = 1 << 5;
const KEY_UP = 1 << 6;
const KEY_DOWN = 1 << 7;
const KEY_PRESS = 1 << 8;
const LOAD = 1 << 9;
const MOUSE_UP = 1 << 10;
const MOUSE_DOWN = 1 << 11;
const MOUSE_MOVE = 1 << 12;
const PRESS = 1 << 13;
const ROLL_OUT = 1 << 14;
const ROLL_OVER = 1 << 15;
const RELEASE = 1 << 16;
const RELEASE_OUTSIDE = 1 << 17;
const UNLOAD = 1 << 18;
}
}
/// A key code used in `ButtonAction` and `ClipAction` key press events.

View File

@ -13,7 +13,6 @@ use crate::{
};
use bitstream_io::BitWrite;
use byteorder::{LittleEndian, WriteBytesExt};
use enumset::EnumSet;
use std::cmp::max;
use std::io::{self, Write};
@ -2176,7 +2175,7 @@ impl<W: Write> Writer<W> {
fn write_clip_actions(&mut self, clip_actions: &[ClipAction]) -> Result<()> {
self.write_u16(0)?; // Reserved
{
let mut all_events = EnumSet::new();
let mut all_events = ClipEventFlag::empty();
for action in clip_actions {
all_events |= action.events;
}
@ -2200,31 +2199,31 @@ impl<W: Write> Writer<W> {
Ok(())
}
fn write_clip_event_flags(&mut self, clip_events: EnumSet<ClipEventFlag>) -> Result<()> {
fn write_clip_event_flags(&mut self, clip_events: ClipEventFlag) -> Result<()> {
// TODO: Assert proper version.
let version = self.version;
let mut bits = self.bits();
bits.write_bit(clip_events.contains(ClipEventFlag::KeyUp))?;
bits.write_bit(clip_events.contains(ClipEventFlag::KeyDown))?;
bits.write_bit(clip_events.contains(ClipEventFlag::MouseUp))?;
bits.write_bit(clip_events.contains(ClipEventFlag::MouseDown))?;
bits.write_bit(clip_events.contains(ClipEventFlag::MouseMove))?;
bits.write_bit(clip_events.contains(ClipEventFlag::Unload))?;
bits.write_bit(clip_events.contains(ClipEventFlag::EnterFrame))?;
bits.write_bit(clip_events.contains(ClipEventFlag::Load))?;
bits.write_bit(clip_events.contains(ClipEventFlag::DragOver))?;
bits.write_bit(clip_events.contains(ClipEventFlag::RollOut))?;
bits.write_bit(clip_events.contains(ClipEventFlag::RollOver))?;
bits.write_bit(clip_events.contains(ClipEventFlag::ReleaseOutside))?;
bits.write_bit(clip_events.contains(ClipEventFlag::Release))?;
bits.write_bit(clip_events.contains(ClipEventFlag::Press))?;
bits.write_bit(clip_events.contains(ClipEventFlag::Initialize))?;
bits.write_bit(clip_events.contains(ClipEventFlag::Data))?;
bits.write_bit(clip_events.contains(ClipEventFlag::KEY_UP))?;
bits.write_bit(clip_events.contains(ClipEventFlag::KEY_DOWN))?;
bits.write_bit(clip_events.contains(ClipEventFlag::MOUSE_UP))?;
bits.write_bit(clip_events.contains(ClipEventFlag::MOUSE_DOWN))?;
bits.write_bit(clip_events.contains(ClipEventFlag::MOUSE_MOVE))?;
bits.write_bit(clip_events.contains(ClipEventFlag::UNLOAD))?;
bits.write_bit(clip_events.contains(ClipEventFlag::ENTER_FRAME))?;
bits.write_bit(clip_events.contains(ClipEventFlag::LOAD))?;
bits.write_bit(clip_events.contains(ClipEventFlag::DRAG_OVER))?;
bits.write_bit(clip_events.contains(ClipEventFlag::ROLL_OUT))?;
bits.write_bit(clip_events.contains(ClipEventFlag::ROLL_OVER))?;
bits.write_bit(clip_events.contains(ClipEventFlag::RELEASE_OUTSIDE))?;
bits.write_bit(clip_events.contains(ClipEventFlag::RELEASE))?;
bits.write_bit(clip_events.contains(ClipEventFlag::PRESS))?;
bits.write_bit(clip_events.contains(ClipEventFlag::INITIALIZE))?;
bits.write_bit(clip_events.contains(ClipEventFlag::DATA))?;
if version >= 6 {
bits.write_ubits(5, 0)?;
bits.write_bit(clip_events.contains(ClipEventFlag::Construct))?;
bits.write_bit(clip_events.contains(ClipEventFlag::KeyPress))?;
bits.write_bit(clip_events.contains(ClipEventFlag::DragOut))?;
bits.write_bit(clip_events.contains(ClipEventFlag::CONSTRUCT))?;
bits.write_bit(clip_events.contains(ClipEventFlag::KEY_PRESS))?;
bits.write_bit(clip_events.contains(ClipEventFlag::DRAG_OUT))?;
bits.write_ubits(8, 0)?;
}
Ok(())