diff options
| author | Paul Buetow <paul@buetow.org> | 2008-06-11 09:48:10 +0000 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2008-06-11 09:48:10 +0000 |
| commit | 0e2e70d5a393024f3ae4a3a3560b4df51075000a (patch) | |
| tree | 27c659d282bec3508304d5fa80a34a1662185950 | |
| parent | 412a1ac0e6311fe39452ae41b6eada4ef17cce34 (diff) | |
More javadoc.
Several bugfixes.
New feauture: Boolean: sim.periodic
A lot of more which i forgot!
41 files changed, 696 insertions, 330 deletions
diff --git a/LaTeX/VERSION b/LaTeX/VERSION index df90c3c..9c283d5 100644 --- a/LaTeX/VERSION +++ b/LaTeX/VERSION @@ -1 +1 @@ -385 +UUID: diff --git a/LaTeX/chapters/titlepage.tex b/LaTeX/chapters/titlepage.tex index f0af26a..48b22f6 100644 --- a/LaTeX/chapters/titlepage.tex +++ b/LaTeX/chapters/titlepage.tex @@ -49,7 +49,7 @@ {\large Prof. Dr. rer. nat. Heinrich Fassbender} {durch\\[0.5cm]} - {\large\bfseries cand. Diplom-Inform. (FH) Paul C. B\"{u}tow\\[0.3cm] } + {\large\bfseries Cand. Inform. (FH) Paul C. B\"{u}tow\\[0.3cm] } {Matthiashofstr. 15\\} {D-52064 Aachen\\} \end{center} diff --git a/LaTeX/diplomarbeit.pdf b/LaTeX/diplomarbeit.pdf Binary files differindex 56a9ba8..81b3d66 100644 --- a/LaTeX/diplomarbeit.pdf +++ b/LaTeX/diplomarbeit.pdf diff --git a/Makefile b/Makefile deleted file mode 100644 index eb5d1f4..0000000 --- a/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -all: - ant compile -clean: - ant clean -test: - ant test -replace: - find ./sources -name '*.java' -exec sh -c 'sed -n "s/$(FROM)/$(INTO)/g; \ - w .tmp" {} && mv -f .tmp {}' \; -stats: - find . -name \*.java | xargs wc -l @@ -1,4 +1,5 @@ Must do: + Color copy constructor in prefs.VSPrefs.copyColors Reliable Multicast Helper: Print warning if not activated protocol while doing a protocol request @@ -5,7 +5,6 @@ <property name="sources" location="sources" /> <property name="dist" location="dist" /> <property name="classes" location="classes" /> - <!-- <property name="contrib" location="contrib" /> --> <target name="init"> <tstamp /> @@ -52,7 +51,6 @@ <target name="testdist" depends="dist,rundist" /> <target name="test" depends="compile,run" /> - <target name="javadoc" description="Generate Javadocs"> <mkdir dir="${basedir}/javadoc/"/> <javadoc destdir="${basedir}/javadoc/"> diff --git a/docs/SERIALIZATION_NOTES.txt b/docs/SERIALIZATION_NOTES.txt index 99cd0fb..44ad0a4 100644 --- a/docs/SERIALIZATION_NOTES.txt +++ b/docs/SERIALIZATION_NOTES.txt @@ -1,5 +1,3 @@ -TODO: RESET BEFORE DESERIALIZATION - VSSerialize prefs(=VSPrefs).serialize writeObject(...) diff --git a/scripts/beforecommit.sh b/scripts/beforecommit.sh new file mode 100755 index 0000000..a06ee8f --- /dev/null +++ b/scripts/beforecommit.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# +# Copyright (c) 2008 Paul C. Buetow, vs@dev.buetow.org +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +./scripts/formatthecode.sh +./scripts/checklinelengths.sh + diff --git a/scripts/checklinelengths.sh b/scripts/checklinelengths.sh new file mode 100755 index 0000000..cf98cd8 --- /dev/null +++ b/scripts/checklinelengths.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# +# Copyright (c) 2008 Paul C. Buetow, vs@dev.buetow.org +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +MAXLEN=80 + +for i in `find ./sources -name \*.java | grep -v VSDefaultPrefs.java` +do + awk -v MAXLEN=$MAXLEN -v file=$i '{ + if (length > MAXLEN) + print file " line " NR " is " length " chars long " + }' $i +done diff --git a/scripts/formatthecode.sh b/scripts/formatthecode.sh new file mode 100755 index 0000000..5733c31 --- /dev/null +++ b/scripts/formatthecode.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# +# Copyright (c) 2008 Paul C. Buetow, vs@dev.buetow.org +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +find ./sources -name \*.java | xargs astyle --style=java --mode=java -n diff --git a/scripts/printstatistics.sh b/scripts/printstatistics.sh new file mode 100755 index 0000000..ca356b5 --- /dev/null +++ b/scripts/printstatistics.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# +# Copyright (c) 2008 Paul C. Buetow, vs@dev.buetow.org +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +find ./sources -name \*.java | xargs wc -l diff --git a/scripts/replaceastring.sh b/scripts/replaceastring.sh new file mode 100755 index 0000000..6b50b83 --- /dev/null +++ b/scripts/replaceastring.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Copyright (c) 2008 Paul C. Buetow, vs@dev.buetow.org +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +FROM=$1 +INTO=$2 + +echo "Replaceing $FROM with $INTO" + +find ./sources -name \*.java -exec sh -c "sed -n 's/$FROM/$INTO/g; \ + w .tmp' {} && mv -f .tmp {}" \; diff --git a/sources/core/VSMessage.java b/sources/core/VSMessage.java index 99c5ce7..1f1ad5b 100644 --- a/sources/core/VSMessage.java +++ b/sources/core/VSMessage.java @@ -28,8 +28,8 @@ import events.*; import prefs.VSPrefs; /** - * This class represents a message which is send from one process to another - * process in the simulator. + * An object of this class represents a message which is sent from one process + * to another process in the simulator. * * @author Paul C. Buetow */ diff --git a/sources/core/VSTask.java b/sources/core/VSTask.java index c1323e8..9ca04e6 100644 --- a/sources/core/VSTask.java +++ b/sources/core/VSTask.java @@ -99,7 +99,7 @@ public class VSTask implements Comparable, VSSerializable { * Instantiates a new task during a deserialization. * * @param serialize the serialize object - * @param process the object input stream + * @param objectInputStream The input stream */ public VSTask(VSSerialize serialize, ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException { @@ -154,11 +154,29 @@ public class VSTask implements Comparable, VSSerializable { } /** + * Checks if the task is using an "internal event". + * + * @return true, if the task is using an internal event + */ + public boolean hasInternalEvent() { + return event instanceof VSAbstractInternalEvent; + } + + /** + * Checks if the task should not get serialized. + * + * @return true, if the task should not get serialized + */ + public boolean hasNotSerializableEvent() { + return event instanceof VSNotSerializable; + } + + /** * Checks if the task is a message receive event. * * @return true, if it is a message receive event */ - public boolean isVSMessageReceiveEvent() { + public boolean hasMessageReceiveEvent() { return event instanceof VSMessageReceiveEvent; } @@ -167,7 +185,7 @@ public class VSTask implements Comparable, VSSerializable { * * @return true, if it is a process recover event */ - public boolean isProcessRecoverEvent() { + public boolean hasProcessRecoverEvent() { return event instanceof VSProcessRecoverEvent; } @@ -366,6 +384,13 @@ public class VSTask implements Comparable, VSSerializable { objectOutputStream.writeObject(new Boolean(false)); objectOutputStream.writeObject(new Integer(process.getProcessNum())); + + if (event.getClassname() == null) + event.init(process); + + if (VSSerialize.DEBUG) + System.out.println("Serializing: " + event.getClassname()); + objectOutputStream.writeObject(event.getClassname()); objectOutputStream.writeObject(new Integer(event.getID())); event.serialize(serialize, objectOutputStream); diff --git a/sources/core/VSTaskManager.java b/sources/core/VSTaskManager.java index d4ee83c..471b54f 100644 --- a/sources/core/VSTaskManager.java +++ b/sources/core/VSTaskManager.java @@ -32,10 +32,9 @@ import simulator.*; import utils.*; /** - * The class VSTaskManager. The task manager is responsible that all tasks - * will get fullfilled in the correct order. Please also read the javadoc - * of the VSTask class. It describes the difference between local and global - * timed tasks. + * The class VSTaskManager, it is responsible that all tasks will get + * fullfilled in the correct order. Please also read the javadoc of the VSTask + * class. It describes the difference between local and global timed tasks. * * @author Paul C. Buetow */ @@ -125,7 +124,7 @@ public class VSTaskManager implements VSSerializable { globalTasks.poll(); redo = true; - if (process.isCrashed() && !task.isProcessRecoverEvent()) { + if (process.isCrashed() && !task.hasProcessRecoverEvent()) { if (task.isProgrammed()) fullfilledProgrammedTasks.add(task); continue; @@ -186,7 +185,7 @@ public class VSTaskManager implements VSSerializable { redo = true; if (process.isCrashed() && - !task.isProcessRecoverEvent()) { + !task.hasProcessRecoverEvent()) { if (task.isProgrammed()) fullfilledProgrammedTasks.add(task); continue; @@ -506,28 +505,34 @@ public class VSTaskManager implements VSSerializable { /** For later backwards compatibility, to add more stuff */ objectOutputStream.writeObject(new Boolean(false)); - ArrayList<VSTask> tasks = new ArrayList<VSTask>(); + ArrayList<VSTask> serializeThoseTasks = new ArrayList<VSTask>(); - for (VSTask task : fullfilledProgrammedTasks) - tasks.add(task); + for (VSTask task : fullfilledProgrammedTasks) { + if (!task.hasNotSerializableEvent()) + serializeThoseTasks.add(task); + } - for (VSTask task : this.globalTasks) - tasks.add(task); + for (VSTask task : globalTasks) { + if (!task.hasNotSerializableEvent()) + serializeThoseTasks.add(task); + } ArrayList<VSProcess> processes = simulatorCanvas.getProcesses(); synchronized (processes) { for (VSProcess process : processes) { VSPriorityQueue<VSTask> localTasks = process.getTasks(); - ArrayList<VSTask> tasks_ = new ArrayList<VSTask>(); - for (VSTask task : localTasks) - tasks.add(task); + for (VSTask task : localTasks) { + if (!task.hasNotSerializableEvent()) + serializeThoseTasks.add(task); + } } } - objectOutputStream.writeObject(new Integer(tasks.size())); - for (VSTask task : tasks) - task.serialize(serialize, objectOutputStream); + objectOutputStream.writeObject( + new Integer(serializeThoseTasks.size())); + for (VSTask task : serializeThoseTasks) + task.serialize(serialize, objectOutputStream); /** For later backwards compatibility, to add more stuff */ objectOutputStream.writeObject(new Boolean(false)); diff --git a/sources/core/time/VSLamportTime.java b/sources/core/time/VSLamportTime.java index aab598a..165adfc 100644 --- a/sources/core/time/VSLamportTime.java +++ b/sources/core/time/VSLamportTime.java @@ -24,8 +24,7 @@ package core.time; /** - * The class VSLamportTime. This class defined how the lamport - * timestamps are represented. + * The class VSLamportTime, defines how the lamport timestamps are represented. * * @author Paul C. Buetow */ diff --git a/sources/core/time/VSVectorTime.java b/sources/core/time/VSVectorTime.java index 1c30af6..ebd5438 100644 --- a/sources/core/time/VSVectorTime.java +++ b/sources/core/time/VSVectorTime.java @@ -26,8 +26,7 @@ package core.time; import java.util.ArrayList; /** - * The class VSVectorTime. This class defined how the vector - * timestamps are represented. + * The class VSVectorTime, defined how the vector timestamps are represented. * * @author Paul C. Buetow */ diff --git a/sources/events/internal/VSAbstractInternalEvent.java b/sources/events/internal/VSAbstractInternalEvent.java new file mode 100644 index 0000000..10a23b7 --- /dev/null +++ b/sources/events/internal/VSAbstractInternalEvent.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2008 Paul C. Buetow, vs@dev.buetow.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * All icons of the icons/ folder are under a Creative Commons + * Attribution-Noncommercial-Share Alike License a CC-by-nc-sa. + * + * The icon's homepage is http://code.google.com/p/ultimate-gnome/ + */ + +package events.internal; + +import java.io.*; + +import events.VSAbstractEvent; +import serialize.VSSerialize; + +/** + * The class VSAbstractInternalEvent, this class if for destinguishing between + * internal and non-internal events. Internal usage only. + * + * @author Paul C. Buetow + */ +abstract public class VSAbstractInternalEvent extends VSAbstractEvent { + /** The serial version uid */ + private static final long serialVersionUID = 1L; + + /* (non-Javadoc) + * @see serialize.VSSerializable#serialize(serialize.VSSerialize, + * java.io.ObjectOutputStream) + */ + public synchronized void serialize(VSSerialize serialize, + ObjectOutputStream objectOutputStream) + throws IOException { + super.serialize(serialize, objectOutputStream); + + /** For later backwards compatibility, to add more stuff */ + objectOutputStream.writeObject(new Boolean(false)); + + /** For later backwards compatibility, to add more stuff */ + objectOutputStream.writeObject(new Boolean(false)); + } + + /* (non-Javadoc) + * @see serialize.VSSerializable#deserialize(serialize.VSSerialize, + * java.io.ObjectInputStream) + */ + @SuppressWarnings("unchecked") + public synchronized void deserialize(VSSerialize serialize, + ObjectInputStream objectInputStream) + throws IOException, ClassNotFoundException { + super.deserialize(serialize, objectInputStream); + + if (VSSerialize.DEBUG) + System.out.println("Deserializing: VSAbstractInternalEvent"); + + /** For later backwards compatibility, to add more stuff */ + objectInputStream.readObject(); + + } +} diff --git a/sources/events/internal/VSMessageReceiveEvent.java b/sources/events/internal/VSMessageReceiveEvent.java index 8972ce5..072c2d6 100644 --- a/sources/events/internal/VSMessageReceiveEvent.java +++ b/sources/events/internal/VSMessageReceiveEvent.java @@ -26,9 +26,8 @@ package events.internal; import java.io.*; import core.VSMessage; -import events.VSAbstractEvent; import protocols.VSAbstractProtocol; -import serialize.VSSerialize; +import serialize.VSNotSerializable; /** * The class VSMessageReceiveEvent. This event is used if a process receives @@ -36,7 +35,8 @@ import serialize.VSSerialize; * * @author Paul C. Buetow */ -public class VSMessageReceiveEvent extends VSAbstractEvent { +public class VSMessageReceiveEvent extends VSAbstractInternalEvent +implements VSNotSerializable { /** The serioal version uid */ private static final long serialVersionUID = 1L; @@ -109,41 +109,4 @@ public class VSMessageReceiveEvent extends VSAbstractEvent { return true; } - - /* (non-Javadoc) - * @see serialize.VSSerializable#serialize(serialize.VSSerialize, - * java.io.ObjectOutputStream) - */ - public synchronized void serialize(VSSerialize serialize, - ObjectOutputStream objectOutputStream) - throws IOException { - super.serialize(serialize, objectOutputStream); - - /** For later backwards compatibility, to add more stuff */ - objectOutputStream.writeObject(new Boolean(false)); - - /** For later backwards compatibility, to add more stuff */ - objectOutputStream.writeObject(new Boolean(false)); - } - - /* (non-Javadoc) - * @see serialize.VSSerializable#deserialize(serialize.VSSerialize, - * java.io.ObjectInputStream) - */ - @SuppressWarnings("unchecked") - public synchronized void deserialize(VSSerialize serialize, - ObjectInputStream objectInputStream) - throws IOException, ClassNotFoundException { - super.deserialize(serialize, objectInputStream); - - if (VSSerialize.DEBUG) - System.out.println("Deserializing: VSProtocolEvent"); - - /** For later backwards compatibility, to add more stuff */ - objectInputStream.readObject(); - - /** For later backwards compatibility, to add more stuff */ - objectInputStream.readObject(); - - } } diff --git a/sources/events/internal/VSProtocolEvent.java b/sources/events/internal/VSProtocolEvent.java index 8d6b2dd..ba110c0 100644 --- a/sources/events/internal/VSProtocolEvent.java +++ b/sources/events/internal/VSProtocolEvent.java @@ -30,7 +30,7 @@ import protocols.VSAbstractProtocol; import serialize.VSSerialize; /** - * The class VSProtocolEvent. This event is used if a protocol (server or + * The class VSProtocolEvent, this event is used if a protocol (server or * client part) of a process gets enabled or disabled, an object of this class * can be for 4 different purporses! Activation of the client protocol, * deactivation of the client protocol, activation of the server protocol, @@ -38,7 +38,7 @@ import serialize.VSSerialize; * * @author Paul C. Buetow */ -public class VSProtocolEvent extends VSAbstractEvent { +public class VSProtocolEvent extends VSAbstractInternalEvent { /** The serial version uid */ private static final long serialVersionUID = 1L; diff --git a/sources/events/internal/VSProtocolScheduleEvent.java b/sources/events/internal/VSProtocolScheduleEvent.java index 99ae020..3c334be 100644 --- a/sources/events/internal/VSProtocolScheduleEvent.java +++ b/sources/events/internal/VSProtocolScheduleEvent.java @@ -27,16 +27,17 @@ import java.io.*; import events.*; import protocols.VSAbstractProtocol; -import serialize.VSSerialize; +import serialize.*; /** - * The class VSProtocolScheduleEvent. This event is used if a protocol (which + * The class VSProtocolScheduleEvent, this event is used if a protocol (which * is a subclass of VSAbstractProtocol) reschedules itself to run again on a * specific time. * * @author Paul C. Buetow */ -public class VSProtocolScheduleEvent extends VSAbstractEvent { +public class VSProtocolScheduleEvent extends VSAbstractInternalEvent +implements VSNotSerializable { /** The serial version uid */ private static final long serialVersionUID = 1L; diff --git a/sources/prefs/2DOCUMENT b/sources/prefs/2DOCUMENT deleted file mode 100644 index e69de29..0000000 --- a/sources/prefs/2DOCUMENT +++ /dev/null diff --git a/sources/prefs/VSDefaultPrefs.java b/sources/prefs/VSDefaultPrefs.java index bbf3c5f..e8ac8b5 100644 --- a/sources/prefs/VSDefaultPrefs.java +++ b/sources/prefs/VSDefaultPrefs.java @@ -27,9 +27,14 @@ import java.awt.Color; import java.awt.event.KeyEvent; /** - * The class VSDefaultPrefs. + * The class VSDefaultPrefs, makes sure that the simulator has its default + * configuration values. (Btw: This is the only class which is allowed to have + * code lines which are longer than 80 chars!) + * + * @author Paul C. Buetow */ public class VSDefaultPrefs extends VSPrefs { + /** The serial version uid */ private static final long serialVersionUID = 1L; /** @@ -256,5 +261,6 @@ public class VSDefaultPrefs extends VSPrefs { initBoolean("sim.message.own.recv", false, "Prozesse empfangen eigene Nachrichten"); initBoolean("sim.message.prob.mean", true, "Mittelwerte der Nachrichtausfallw'k. bilden"); initBoolean("sim.messages.relevant", true, "Nur alle relevanten Nachrichten ausliefern"); + initBoolean("sim.periodic", false, "Simulation periodisch wiederholen"); } } diff --git a/sources/prefs/VSPrefs.java b/sources/prefs/VSPrefs.java index f17732c..e9ede88 100644 --- a/sources/prefs/VSPrefs.java +++ b/sources/prefs/VSPrefs.java @@ -30,7 +30,10 @@ import java.util.*; import serialize.*; /** - * The class VSPrefs. + * The class VSPrefs, this class is for dynamic data storage. It can hold + * various different types such as Boolean, Floats, Integers, Strings, Colors. + * + * @author Paul C. Buetow */ public class VSPrefs implements VSSerializable { /** The Constant BOOLEAN_PREFIX. */ @@ -90,9 +93,6 @@ public class VSPrefs implements VSSerializable { /** The Constant serialVersionUID. */ private static final long serialVersionUID = 4L; - /** The Constant PREFERENCES_FILENAME. */ - protected final static String PREFERENCES_FILENAME = "vs.dat"; - /** The id counter. */ private static int idCounter; @@ -201,7 +201,8 @@ public class VSPrefs implements VSSerializable { * @param key the key * @param settingRestriction the setting restriction */ - public synchronized void initRestriction(String key, VSPrefsRestriction settingRestriction) { + public synchronized void initRestriction(String key, + VSPrefsRestriction settingRestriction) { restrictions.put(key, settingRestriction); } @@ -589,7 +590,8 @@ public class VSPrefs implements VSSerializable { * @param descr the descr < |
