Interface MapModel<G extends GameObject<G,​A,​R>,​A extends MapArchObject<A>,​R extends Archetype<G,​A,​R>>

  • All Superinterfaces:
    java.lang.Iterable<MapSquare<G,​A,​R>>, java.io.Serializable
    All Known Implementing Classes:
    DefaultMapModel

    public interface MapModel<G extends GameObject<G,​A,​R>,​A extends MapArchObject<A>,​R extends Archetype<G,​A,​R>>
    extends java.lang.Iterable<MapSquare<G,​A,​R>>, java.io.Serializable
    A MapModel reflects the data of a map. This MapModel interface covers the similarities between the current CFEditor and DaiEditor implementations.

    Transaction System

    The purpose of the transaction system in MapModel is to allow several subsequent changes to the model to be collected as a single big change before the registered listeners (usually the user interface) gets notified. This prevents the user interface from performing hundreds of updates when a single one would be enough. The transaction system will also be used for implementing undo / redo.

    Concurrency

    It's not purpose of the transaction system to provide concurrent transactions for concurrent threads. A MapModel will protect itself against concurrent modification.

    Performance

    The transaction system is efficient-safe. The following operations are very cheap:

    • Beginning a nested transaction
    • Ending a nested transaction
    • Ending an outermost transaction without having changed something
    Whether beginning the outermost transaction will be a cheap operation is not yet decided.

    Transactions are recorded.

    It is not (yet?) the purpose of the transaction system to provide real transactions (ACID). Queries to the MapModel during an ongoing transaction will reflect the intermediate state. And there is no rollback yet, but this is planned for future as it's required for undo anyway.

    Future

    The following features are not yet implemented but planned.

    Undo System

    The transaction system will serve as a base for an undo / redo system. Beginning the outermost transaction stores a new undo record in the undo buffer. An undo record consists of the transaction's name plus the current map state.
    Invariant:
    !isAnyTransactionActive() || getTransactionDepth() > 0
    • Method Detail

      • mapClosed

        void mapClosed()
        This function must be called if this instance is freed.
      • clearMap

        void clearMap()
        Clears this map completely. After invoking this method, no objects will remain on this map.
      • isEmpty

        boolean isEmpty()
        Returns whether the map is empty.
        Returns:
        true if the map is empty, or false if the map is not empty
      • getMapArchObject

        @NotNull
        A getMapArchObject()
        Returns the Map Arch Object with the meta information about the map.
        Returns:
        the map arch object with the meta information about the map
      • addMapModelListener

        void addMapModelListener​(@NotNull
                                 @NotNull MapModelListener<G,​A,​R> listener)
        Register a map listener.
        Parameters:
        listener - the listener to register
      • removeMapModelListener

        void removeMapModelListener​(@NotNull
                                    @NotNull MapModelListener<G,​A,​R> listener)
        Unregister a map listener.
        Parameters:
        listener - the listener to unregister
      • addMapTransactionListener

        void addMapTransactionListener​(@NotNull
                                       @NotNull MapTransactionListener<G,​A,​R> listener)
        Registers a map transaction listener.
        Parameters:
        listener - the the listener to register
      • removeMapTransactionListener

        void removeMapTransactionListener​(@NotNull
                                          @NotNull MapTransactionListener<G,​A,​R> listener)
        Unregisters a map transaction listener.
        Parameters:
        listener - the listener to unregister
      • beginSquareChange

        void beginSquareChange​(@NotNull
                               @NotNull MapSquare<G,​A,​R> mapSquare)
        Method to notify the model that a map square is about to change.
        Parameters:
        mapSquare - the map square that is about to change
      • endSquareChange

        void endSquareChange​(@NotNull
                             @NotNull MapSquare<G,​A,​R> mapSquare)
        Method to notify the model that a map square was changed. A change to a square is atomic if getTransactionDepth() returns 0, otherwise it is transactional. The model then notifies the registered listeners of the changes.
        Parameters:
        mapSquare - the map square that has changed
      • beginGameObjectChange

        void beginGameObjectChange​(@NotNull
                                   G gameObject)
        Method to notify the model that a game object is about to change.
        Parameters:
        gameObject - the game object that is about to change
      • endGameObjectChange

        void endGameObjectChange​(@NotNull
                                 G gameObject)
        Method to notify the model that a game object was changed. A change to a game object is atomic if getTransactionDepth() returns 0, otherwise it is transactional. The model then notifies the registered listeners of the changes.
        Parameters:
        gameObject - the game object that has changed
      • transientGameObjectChange

        void transientGameObjectChange​(@NotNull
                                       G gameObject)
        Method to notify the model that a game object was changed but need not be restored by undo/redo. A change to a game object is atomic if getTransactionDepth() returns 0, otherwise it is transactional. The model then notifies the registered listeners of the changes.
        Parameters:
        gameObject - the game object that has changed
      • beginTransaction

        void beginTransaction​(@NotNull
                              @NotNull java.lang.String name)
        Starts a new transaction. Transactions may be nested. Transactions serve the purpose of firing events to the views when more changes are known to come before the view is really required to update. Each invocation of this function requires its own invocation of endTransaction().

        A transaction has a name. The name of the outermost transaction is used as a String presented to the user for undoing the operation enclosed by that transaction.

        Beginning a nested transaction is a cheap operation.

        Parameters:
        name - the name of the transaction
        See Also:
        endTransaction(), endTransaction(boolean), endAllTransactions(), getTransactionDepth(), isAnyTransactionActive()
      • endTransaction

        void endTransaction​(boolean fireEvent)
        End a transaction. Invoking this method will reduce the transaction depth by only 1.

        Ending a nested operation is a cheap operation. Ending a transaction without changes also is a cheap operation.

        If the last transaction is ended, the changes are committed.

        An example where setting fireEvent to true is useful even though the outermost transaction is not ended is when during painting the UI should be updated though painting is not finished.

        Parameters:
        fireEvent - true if an event should be fired even in case this doesn't end the outermost transaction.
        See Also:
        beginTransaction(String), endTransaction(), endAllTransactions(), getTransactionDepth(), isAnyTransactionActive()
        Note:
        If the outermost transaction is ended, fireEvent is ignored and the event is always fired., An event is never fired when there were no changes, no matter whether the outermost transaction is ended or fireEvent is set to true., If the event is fired, the internal change list is not cleared.
      • getMapSquare

        @NotNull
        @NotNull MapSquare<G,​A,​R> getMapSquare​(@NotNull
                                                           @NotNull java.awt.Point pos)
        Get the square at a specified location.
        Parameters:
        pos - location to get square at
        Returns:
        square at p
        Throws:
        java.lang.IndexOutOfBoundsException - in case p specifies a location that's not valid within this map model
      • addObjectListToMap

        void addObjectListToMap​(@NotNull
                                @NotNull java.lang.Iterable<G> objects)
        Adds a list of GameObjects to this map.
        Parameters:
        objects - the game objects to add
      • addGameObjectToMap

        void addGameObjectToMap​(@NotNull
                                G gameObject,
                                @NotNull
                                @NotNull java.awt.Point pos,
                                @NotNull
                                @NotNull InsertionMode<G,​A,​R> insertionMode)
        Add a gameObject to the map. Including multi square objects. This function allows to insert any given GameObject. Make sure that the given gameObject is a new and unlinked object.
        Parameters:
        gameObject - The new GameObject with set destination coordinates to be linked onto the map.
        pos - the insert location
        insertionMode - the insertion mode to use
      • moveEnv

        void moveEnv​(@NotNull
                     G gameObject,
                     @NotNull
                     @NotNull java.awt.Point pos,
                     @NotNull
                     G nextGameObject)
        Moves a GameObject to its environment.
        Parameters:
        gameObject - the game object to move
        pos - the insertion position
        nextGameObject - the next game object
      • moveInv

        void moveInv​(@NotNull
                     G gameObject,
                     @NotNull
                     @NotNull GameObject<G,​A,​R> prevGameObject)
        Moves a GameObject to the inventory of another game object.
        Parameters:
        gameObject - the game object to move
        prevGameObject - the previous game object
      • insertBaseObject

        @Nullable
        G insertBaseObject​(@NotNull
                           @NotNull BaseObject<G,​A,​R,​?> baseObject,
                           @NotNull
                           @NotNull java.awt.Point pos,
                           boolean allowMany,
                           boolean join,
                           @NotNull
                           @NotNull InsertionMode<G,​A,​R> insertionMode)
        Inserts a BaseObject to a map. Archetypes are instantiated, game objects are cloned. The direction of the inserted game object is set to the direction of the archetype chooser. This function allows multi-square game objects.
        Parameters:
        baseObject - the base object
        pos - the insert-location on this map
        allowMany - whether duplicates are allowed
        join - whether to auto-join the inserted game object
        insertionMode - the insertion mode to use
        Returns:
        the inserted game object or null if nothing was inserted
      • insertArchToMap

        @Nullable
        G insertArchToMap​(@NotNull
                          @NotNull BaseObject<G,​A,​R,​?> templateBaseObject,
                          @Nullable
                          G nextGameObject,
                          @NotNull
                          @NotNull java.awt.Point pos,
                          boolean join)
        Insert a game object to the map at a specified position. This function allows either to choose from the archetypes or to insert a copy from an existing game object. It also works for container-inventory.
        Parameters:
        templateBaseObject - a clone copy of this game object gets inserted to the map; it can be an archetype of a game object
        nextGameObject - the new game object gets inserted before this; if null, the game object gets inserted at bottom
        pos - the map position to insert the new game object
        join - if set, auto-joining is supported
        Returns:
        the inserted game object, or null if an error occurred
      • removeGameObject

        void removeGameObject​(@NotNull
                              G gameObject,
                              boolean join)
        Delete an existing GameObject from the map.
        Parameters:
        gameObject - the game object to remove
        join - if set, auto-joining is supported
      • isMultiArchFittingToMap

        boolean isMultiArchFittingToMap​(@NotNull
                                        @NotNull Archetype<G,​A,​R> archetype,
                                        @NotNull
                                        @NotNull java.awt.Point pos,
                                        boolean allowDouble)
        Checks whether an GameObject (multi-arch) would still fit on this map.
        Parameters:
        archetype - the archetype to check
        pos - position of multi-square head
        allowDouble - whether overlapping multi-square arches should be allowed (check is done using the archetype name)
        Returns:
        whether the multi-arch would still fit on this map
        Return Value:
        true if the multi-square archetype would still fit on this map, false otherwise
      • setErrors

        void setErrors​(@NotNull
                       @NotNull ErrorCollector<G,​A,​R> errors)
        Sets the errors in this map.
        Parameters:
        errors - the errors
      • getErrors

        @NotNull
        @NotNull ErrorCollector<G,​A,​R> getErrors()
        Gets the errors in this map.
        Returns:
        the errors
      • isAreaEmpty

        boolean isAreaEmpty​(int left,
                            int top,
                            int width,
                            int height)
        Checks whether an area of a map is completely empty.
        Parameters:
        left - the left border of the area
        top - the top border of the area
        width - the with of the area
        height - the height of the area
        Returns:
        whether the area is completely empty
      • addActiveEditType

        void addActiveEditType​(int editType)
        Add edit type to the bitmask of active types. If this is a new type, it gets calculated for every arch on the map. Once it is calculated, we save that state in 'activeEditType' so we don't need to do it again.
        Parameters:
        editType - new edit type
      • setMapFile

        void setMapFile​(@Nullable
                        @Nullable MapFile mapFile)
        Sets the map file.
        Parameters:
        mapFile - the map file or null if the map has not yet been saved
      • getMapFile

        @Nullable
        @Nullable MapFile getMapFile()
        Returns the map file.
        Returns:
        the map file or null if the map has not yet been saved
      • getMapFile

        @NotNull
        @NotNull MapFile getMapFile​(@NotNull
                                    @NotNull MapPath mapPath)
                             throws SameMapException,
                                    UnsavedMapException
        Returns the map file for a map that can be reached by following a MapPath from this map.
        Parameters:
        mapPath - the map path to follow
        Returns:
        the map file
        Throws:
        SameMapException - of the destination map file is the same as this map file
        UnsavedMapException - if this map is not saved and therefore its map file is unknown
      • getAllGameObjects

        @NotNull
        @NotNull java.util.List<G> getAllGameObjects()
        Returns all game objects. Only top-level head parts are returned; tail parts are ignored as are objects in inventories.
        Returns:
        all game objects
      • isModified

        boolean isModified()
        Return whether the map has been modified from the on-disk state.
        Returns:
        true if the map has been modified from the on-disk state
      • resetModified

        void resetModified()
        Resets the modified flag to false.
      • facesReloaded

        void facesReloaded()
        Will be called whenever the archetype faces have been reloaded.
      • nextPoint

        void nextPoint​(java.awt.Point point,
                       int direction)
        Moves the given point forward or backward one map square.
        Parameters:
        point - the point to start with and modify
        direction - the direction (-1 or +1)