Repository: servo/servo
File: components/script/dom/webgl/webglprogram.rs (Rust)

Code before:
use script_bindings::weakref::WeakRef;

use crate::dom::bindings::cell::{DomRefCell, Ref};
use crate::dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants as constants2;
use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object};
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::webgl::webglactiveinfo::WebGLActiveInfo;
use crate::dom::webgl::webglobject::WebGLObject;
use crate::dom::webgl::webglrenderingcontext::{Operation, WebGLRenderingContext};
use crate::dom::webgl::webglshader::WebGLShader;
use crate::dom::webgl::webgluniformlocation::WebGLUniformLocation;
use crate::dom::webglrenderingcontext::capture_webgl_backtrace;
use crate::script_runtime::CanGc;

#[derive(JSTraceable, MallocSizeOf)]
struct DroppableWebGLProgram {
    #[no_trace]
    id: WebGLProgramId,
    context: WeakRef<WebGLRenderingContext>,
    fragment_shader: Option<WeakRef<WebGLShader>>,
    vertex_shader: Option<WeakRef<WebGLShader>>,
    marked_for_deletion: Cell<bool>,
    is_in_use: Cell<bool>,
}

impl DroppableWebGLProgram {
    fn new(
        id: WebGLProgramId,
        context: &WebGLRenderingContext,
        fragment_shader: Option<&WebGLShader>,
        vertex_shader: Option<&WebGLShader>,
    ) -> Self {
        Self {
            id,
            context: WeakRef::new(context),
            fragment_shader: fragment_shader.map(WeakRef::new),
            vertex_shader: vertex_shader.map(WeakRef::new),
            marked_for_deletion: Default::default(),
            is_in_use: Default::default(),
        }
    }
}

impl DroppableWebGLProgram {
    fn attach_shader<'a>(&mut self, shader: &'a WebGLShader) -> WebGLResult<&'a WebGLShader> {
        if self.is_deleted() || shader.is_deleted() {
            return Err(WebGLError::InvalidOperation);
        }

Review comment (suggestion):
Since we have a RefCell around DroppableWebGLProgram, we don't need Cell for these fields any more. We can use `&mut self` in methods that need to change them.

Code after:
use script_bindings::weakref::WeakRef;

use crate::dom::bindings::cell::{DomRefCell, Ref};
use crate::dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants as constants2;
use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object};
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::webgl::webglactiveinfo::WebGLActiveInfo;
use crate::dom::webgl::webglobject::WebGLObject;
use crate::dom::webgl::webglrenderingcontext::{Operation, WebGLRenderingContext};
use crate::dom::webgl::webglshader::WebGLShader;
use crate::dom::webgl::webgluniformlocation::WebGLUniformLocation;
use crate::dom::webglrenderingcontext::capture_webgl_backtrace;
use crate::script_runtime::CanGc;

#[derive(JSTraceable, MallocSizeOf)]
struct DroppableWebGLProgram {
    #[no_trace]
    id: WebGLProgramId,
    context: WeakRef<WebGLRenderingContext>,
    fragment_shader: Option<WeakRef<WebGLShader>>,
    vertex_shader: Option<WeakRef<WebGLShader>>,
    marked_for_deletion: bool,
    is_in_use: bool,
}

impl DroppableWebGLProgram {
    fn new(id: WebGLProgramId, context: &WebGLRenderingContext) -> Self {
        Self {
            id,
            context: WeakRef::new(context),
            fragment_shader: None,
            vertex_shader: None,
            marked_for_deletion: Default::default(),
            is_in_use: Default::default(),
        }
    }
}

impl DroppableWebGLProgram {
    fn attach_shader<'a>(&mut self, shader: &'a WebGLShader) -> WebGLResult<&'a WebGLShader> {
        if self.is_deleted() || shader.is_deleted() {
            return Err(WebGLError::InvalidOperation);
        }
        let shader_slot = match shader.gl_type() {
            constants::FRAGMENT_SHADER => &mut self.fragment_shader,
            constants::VERTEX_SHADER => &mut self.vertex_shader,
            _ => {
                error!("detachShader: Unexpected shader type");