<commit_before>//Copyright 2015 <NAME>
//
//Licensed under the Apache License,Version2.0(the"License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing,software
//distributed under the License is distributed on an"AS IS"BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package org.westmalle.wayland.core;

import com.google.auto.factory.AutoFactory;
import com.google.auto.factory.Provided;
import org.freedesktop.wayland.server.DestroyListener;
import org.freedesktop.wayland.server.ShmBuffer;
import org.freedesktop.wayland.server.WlBufferResource;
import org.freedesktop.wayland.server.WlCallbackResource;
import org.freedesktop.wayland.server.WlCompositorResource;
import org.freedesktop.wayland.server.WlKeyboardResource;
import org.freedesktop.wayland.server.WlRegionResource;
import org.westmalle.wayland.core.calc.Mat4;
import org.westmalle.wayland.core.calc.Vec4;
import org.westmalle.wayland.core.events.KeyboardFocusGained;
import org.westmalle.wayland.core.events.KeyboardFocusLost;
import org.westmalle.wayland.core.events.Signal;
import org.westmalle.wayland.core.events.Slot;
import org.westmalle.wayland.protocol.WlCompositor;
import org.westmalle.wayland.protocol.WlRegion;

import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;

@AutoFactory(className = "SurfaceFactory",
             allowSubclasses = true)
public class Surface {

    /*
     * Signals
     */
    @Nonnull
    private final Signal<KeyboardFocusLost, Slot<KeyboardFocusLost>>     keyboardFocusLostSignal   = new Signal<>();
    @Nonnull
    private final Signal<KeyboardFocusGained, Slot<KeyboardFocusGained>> keyboardFocusGainedSignal = new Signal<>();
    @Nonnull
    private final Signal<Point, Slot<Point>>                             positionSignal            = new Signal<>();
    @Nonnull
    private final Signal<SurfaceState, Slot<SurfaceState>>               applySurfaceStateSignal   = new Signal<>();

    @Nonnull
    private final FiniteRegionFactory finiteRegionFactory;
    @Nonnull
    private final Compositor          compositor;
    @Nonnull
    private final Renderer            renderer;
    @Nonnull
    private final List<WlCallbackResource>  callbacks                    = new LinkedList<>();
    @Nonnull
    private final Set<WlKeyboardResource>   keyboardFocuses              = new HashSet<>();
    @Nonnull
    private       Optional<Role>            surfaceRole                  = Optional.empty();
    @Nonnull
    private       Optional<DestroyListener> pendingBufferDestroyListener = Optional.empty();

    /*
     * pending state
     */
    @Nonnull
    private SurfaceState pendingState = SurfaceState.builder()
                                                    .build();
    /*
     * committed state
     */
    @Nonnull
    private SurfaceState state        = SurfaceState.builder()
                                                    .build();
    /*
     * committed derived states
     */
    private boolean destroyed;
    @Nonnull
    private Mat4      transform        = Transforms.NORMAL;
    @Nonnull
    private Mat4      inverseTransform = Transforms.NORMAL;
    @Nonnull
    private Rectangle size             = Rectangle.ZERO;

    Surface(@Nonnull @Provided final FiniteRegionFactory finiteRegionFactory,
            @Nonnull @Provided final Compositor compositor,
            @Nonnull @Provided final Renderer renderer) {
        this.finiteRegionFactory = finiteRegionFactory;
        this.compositor = compositor;
        this.renderer = renderer;
    }

    @Nonnull
    public Signal<KeyboardFocusLost, Slot<KeyboardFocusLost>> getKeyboardFocusLostSignal() {
        return this.keyboardFocusLostSignal;
    }

    @Nonnull
    public Signal<KeyboardFocusGained, Slot<KeyboardFocusGained>> getKeyboardFocusGainedSignal() {
        return this.keyboardFocusGainedSignal;
    }

    public boolean isDestroyed() {
        return this.destroyed;
    }

    @Nonnull
    public Surface markDestroyed() {
        this.destroyed = true;
        return this;
    }

    @Nonnull
    public Surface markDamaged(@Nonnull final Rectangle damage) {
        final Region newDamage = getPendingState().getDamage()
                                                  .orElseGet(this.finiteRegionFactory::create)
                                                  .add(damage);
        final SurfaceState pendingSurfaceState = getPendingState().toBuilder()
                                                                  .damage(Optional.of(newDamage))
                                                                  .build();
        setPendingState(pendingSurfaceState);
        return this;
    }

    @Nonnull
    public SurfaceState getPendingState() {
        return this.pendingState;
    }

    public void setPendingState(@Nonnull final SurfaceState pendingState) {
        this.pendingState = pendingState;
    }

    @Nonnull
    public Surface attachBuffer(@Nonnull final WlBufferResource buffer,
                                final int dx,
                                final int dy) {
        getPendingState().getBuffer()
                         .ifPresent(wlBufferResource -> wlBufferResource.unregister(this.pendingBufferDestroyListener.get()));
        this.pendingBufferDestroyListener = Optional.of(this::detachBuffer);
        buffer.register(this.pendingBufferDestroyListener.get());
        final SurfaceState pendingSurfaceState = getPendingState().toBuilder()
                                                                  .buffer(Optional.of(buffer))
                                                                  .positionTransform(Transforms.TRANSLATE(dx,
                                                                                                          dy)
                                                                                               .multiply(getState().getPositionTransform()))
                                                                  .build();
        setPendingState(pendingSurfaceState);
        return this;
    }

    @Nonnull
    public SurfaceState getState() {
        return this.state;
    }

    public void setState(@Nonnull final SurfaceState state) {
        this.state = state;
    }

    @Nonnull
    public Optional<Role> getRole() {
        return this.surfaceRole;
    }

    public void setRole(@Nonnull final Role role) {
        this.surfaceRole = Optional.of(role);
    }

    @Nonnull
    public Surface commit() {
        final Optional<WlBufferResource> buffer = getState().getBuffer();<commit_msg>make names a bit clearer<commit_after>//Copyright 2015 <NAME>
//
//Licensed under the Apache License,Version2.0(the"License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing,software
//distributed under the License is distributed on an"AS IS"BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package org.westmalle.wayland.core;

import com.google.auto.factory.AutoFactory;
import com.google.auto.factory.Provided;
import org.freedesktop.wayland.server.DestroyListener;
import org.freedesktop.wayland.server.ShmBuffer;
import org.freedesktop.wayland.server.WlBufferResource;
import org.freedesktop.wayland.server.WlCallbackResource;
import org.freedesktop.wayland.server.WlCompositorResource;
import org.freedesktop.wayland.server.WlKeyboardResource;
import org.freedesktop.wayland.server.WlRegionResource;
import org.westmalle.wayland.core.calc.Mat4;
import org.westmalle.wayland.core.calc.Vec4;
import org.westmalle.wayland.core.events.KeyboardFocusGained;
import org.westmalle.wayland.core.events.KeyboardFocusLost;
import org.westmalle.wayland.core.events.Signal;
import org.westmalle.wayland.core.events.Slot;
import org.westmalle.wayland.protocol.WlCompositor;
import org.westmalle.wayland.protocol.WlRegion;

import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;

@AutoFactory(className = "SurfaceFactory",
             allowSubclasses = true)
public class Surface {

    /*
     * Signals
     */
    @Nonnull
    private final Signal<KeyboardFocusLost, Slot<KeyboardFocusLost>>     keyboardFocusLostSignal   = new Signal<>();
    @Nonnull
    private final Signal<KeyboardFocusGained, Slot<KeyboardFocusGained>> keyboardFocusGainedSignal = new Signal<>();
    @Nonnull
    private final Signal<Point, Slot<Point>>                             positionSignal            = new Signal<>();
    @Nonnull
    private final Signal<SurfaceState, Slot<SurfaceState>>               applySurfaceStateSignal   = new Signal<>();

    @Nonnull
    private final FiniteRegionFactory finiteRegionFactory;
    @Nonnull
    private final Compositor          compositor;
    @Nonnull
    private final Renderer            renderer;
    @Nonnull
    private final List<WlCallbackResource>  callbacks                    = new LinkedList<>();
    @Nonnull
    private final Set<WlKeyboardResource>   keyboardFocuses              = new HashSet<>();
    @Nonnull
    private       Optional<Role>            surfaceRole                  = Optional.empty();
    @Nonnull
    private       Optional<DestroyListener> pendingBufferDestroyListener = Optional.empty();

    /*
     * pending state
     */
    @Nonnull
    private SurfaceState pendingState = SurfaceState.builder()
                                                    .build();
    /*
     * committed state
     */
    @Nonnull
    private SurfaceState state        = SurfaceState.builder()
                                                    .build();
    /*
     * committed derived states
     */
    private boolean destroyed;
    @Nonnull
    private Mat4      transform        = Transforms.NORMAL;
    @Nonnull
    private Mat4      inverseTransform = Transforms.NORMAL;
    @Nonnull
    private Rectangle size             = Rectangle.ZERO;

    Surface(@Nonnull @Provided final FiniteRegionFactory finiteRegionFactory,
            @Nonnull @Provided final Compositor compositor,
            @Nonnull @Provided final Renderer renderer) {
        this.finiteRegionFactory = finiteRegionFactory;
        this.compositor = compositor;
        this.renderer = renderer;
    }

    @Nonnull
    public Signal<KeyboardFocusLost, Slot<KeyboardFocusLost>> getKeyboardFocusLostSignal() {
        return this.keyboardFocusLostSignal;
    }

    @Nonnull
    public Signal<KeyboardFocusGained, Slot<KeyboardFocusGained>> getKeyboardFocusGainedSignal() {
        return this.keyboardFocusGainedSignal;
    }

    public boolean isDestroyed() {
        return this.destroyed;
    }

    @Nonnull
    public Surface markDestroyed() {
        this.destroyed = true;
        return this;
    }

    @Nonnull
    public Surface markDamaged(@Nonnull final Rectangle damage) {
        final Region newDamage = getPendingState().getDamage()
                                                  .orElseGet(this.finiteRegionFactory::create)
                                                  .add(damage);
        final SurfaceState pendingSurfaceState = getPendingState().toBuilder()
                                                                  .damage(Optional.of(newDamage))
                                                                  .build();
        setPendingState(pendingSurfaceState);
        return this;
    }

    @Nonnull
    public SurfaceState getPendingState() {
        return this.pendingState;
    }

    public void setPendingState(@Nonnull final SurfaceState pendingState) {
        this.pendingState = pendingState;
    }

    @Nonnull
    public Surface attachBuffer(@Nonnull final WlBufferResource wlBufferResource,
                                final int dx,
                                final int dy) {
        getPendingState().getBuffer()
                         .ifPresent(previousWlBufferResource -> previousWlBufferResource.unregister(this.pendingBufferDestroyListener.get()));
        this.pendingBufferDestroyListener = Optional.of(this::detachBuffer);
        wlBufferResource.register(this.pendingBufferDestroyListener.get());
        final SurfaceState pendingSurfaceState = getPendingState().toBuilder()
                                                                  .buffer(Optional.of(wlBufferResource))
                                                                  .positionTransform(Transforms.TRANSLATE(dx,
                                                                                                          dy)
                                                                                               .multiply(getState().getPositionTransform()))
                                                                  .build();
        setPendingState(pendingSurfaceState);
        return this;
    }

    @Nonnull
    public SurfaceState getState() {
        return this.state;
    }

    public void setState(@Nonnull final SurfaceState state) {
        this.state = state;
    }

    @Nonnull
    public Optional<Role> getRole() {
        return this.surfaceRole;
    }

    public void setRole(@Nonnull final Role role) {
        this.surfaceRole = Optional.of(role);
    }

    @Nonnull
    public Surface commit() {
        final Optional<WlBufferResource> buffer = getState().getBuffer();
{'fraction_non_alphanumeric': 0.08010794687877282, 'fraction_numerical': 0.0017044244016760173, 'mean_word_length': 2.1161761451648595, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 54, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3749197', 'n_tokens_mistral': 3517, 'n_tokens_neox': 3424, 'n_words': 787}