001/*
002 * Copyright (c) 2022-2024 See AUTHORS file.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 */
017
018package com.github.tommyettinger.kryo.simplegraphs;
019
020import com.esotericsoftware.kryo.Kryo;
021import com.esotericsoftware.kryo.Serializer;
022import com.esotericsoftware.kryo.io.Input;
023import com.esotericsoftware.kryo.io.Output;
024import space.earlygrey.simplegraphs.Connection;
025import space.earlygrey.simplegraphs.UndirectedGraph;
026
027import java.util.Collection;
028
029/**
030 * Kryo {@link Serializer} for simple-graphs {@link UndirectedGraph}s.
031 * You should register the vertex type when you register this as the serializer for UndirectedGraph.
032 */
033public class UndirectedGraphSerializer extends Serializer<UndirectedGraph<?>> {
034
035    public UndirectedGraphSerializer() {
036        setAcceptsNull(false);
037    }
038
039    @Override
040    public void write(final Kryo kryo, final Output output, final UndirectedGraph<?> data) {
041        Collection<?> vertices = data.getVertices();
042        Collection<? extends Connection<?>> edges = data.internals().getConnections();
043        int length = vertices.size();
044        output.writeInt(length, true);
045        for(Object v : vertices) {
046            kryo.writeClassAndObject(output, v);
047        }
048        length = edges.size();
049        output.writeInt(length, true);
050        for(Connection<?> e : edges) {
051            kryo.writeClassAndObject(output, e.getA());
052            kryo.writeClassAndObject(output, e.getB());
053//            kryo.writeClassAndObject(output, e.getWeightFunction());
054            output.writeFloat(e.getWeight());
055        }
056    }
057
058    @SuppressWarnings({"rawtypes", "unchecked", "UnnecessaryLocalVariable"})
059    @Override
060    public UndirectedGraph<?> read(final Kryo kryo, final Input input, final Class<? extends UndirectedGraph<?>> dataClass) {
061        UndirectedGraph<?> graph = new UndirectedGraph<>();
062        UndirectedGraph raw = graph;
063        int length = input.readInt(true);
064        for (int i = 0; i < length; i++) {
065            raw.addVertex(kryo.readClassAndObject(input));
066        }
067        length = input.readInt(true);
068        for (int i = 0; i < length; i++) {
069//            raw.addEdge(kryo.readClassAndObject(input), kryo.readClassAndObject(input), (WeightFunction) kryo.readClassAndObject(input));
070            raw.addEdge(kryo.readClassAndObject(input), kryo.readClassAndObject(input), input.readFloat());
071        }
072        return graph;
073    }
074
075    @SuppressWarnings({"rawtypes", "unchecked", "UnnecessaryLocalVariable"})
076    @Override
077    public UndirectedGraph<?> copy(Kryo kryo, UndirectedGraph<?> original) {
078        UndirectedGraph<?> graph = new UndirectedGraph<>();
079        UndirectedGraph raw = graph;
080        Collection<?> vertices = graph.getVertices();
081        for(Object v : vertices){
082            raw.addVertex(kryo.copy(v));
083        }
084        Collection<? extends Connection<?>> edges = graph.internals().getConnections();
085        for(Connection<?> e : edges){
086//            raw.addEdge(kryo.copy(e.getA()), kryo.copy(e.getB()), e.getWeightFunction());
087            raw.addEdge(kryo.copy(e.getA()), kryo.copy(e.getB()), e.getWeight());
088        }
089        return graph;
090    }
091}