lipsync/trunk/Boare.Lib.Vsq/VsqBPList.cs

329 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* VsqBPList.cs
* Copyright (c) 2008-2009 kbinani
*
* This file is part of Boare.Lib.Vsq.
*
* Boare.Lib.Vsq is free software; you can redistribute it and/or
* modify it under the terms of the BSD License.
*
* Boare.Lib.Vsq 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace Boare.Lib.Vsq {
/// <summary>
/// BPListのデータ部分を取り扱うためのクラス。
/// </summary>
[Serializable]
public class VsqBPList : ICloneable {
private SortedList<int, VsqBPPair> m_list = new SortedList<int, VsqBPPair>();
public int Default = 0;
public int Maximum = 127;
public int Minimum = 0;
/// <summary>
/// このリストに設定されたidの最大値次にデータ点が追加されたときは個の値+1がidとして利用される削除された場合でも減らない
/// </summary>
private int m_max_id = 0;
private class KeyClockIterator : Iterator {
private SortedList<int, VsqBPPair> m_list;
private int m_pos;
public KeyClockIterator( SortedList<int, VsqBPPair> list ) {
m_list = list;
m_pos = -1;
}
public bool hasNext() {
if ( m_pos + 1 < m_list.Keys.Count ) {
return true;
} else {
return false;
}
}
public object next() {
m_pos++;
return m_list.Keys[m_pos];
}
public void remove() {
if ( 0 <= m_pos && m_pos < m_list.Keys.Count ) {
int key = m_list.Keys[m_pos];
m_list.Remove( key );
}
}
}
public VsqBPList()
: this( 0, 0, 64 ) {
}
/// <summary>
/// XMLシリアライズ用
/// </summary>
public string Data {
get {
string ret = "";
int count = -1;
foreach ( int key in m_list.Keys ) {
count++;
ret += (count == 0 ? "" : "," ) + key + "=" + m_list[key].value;
}
return ret;
}
set {
m_list.Clear();
m_max_id = 0;
string[] spl = value.Split( ',' );
for ( int i = 0; i < spl.Length; i++ ) {
string[] spl2 = spl[i].Split( '=' );
if ( spl2.Length < 2 ) {
continue;
}
try {
m_list.Add( int.Parse( spl2[0] ), new VsqBPPair( int.Parse( spl2[1] ), m_max_id + 1 ) );
m_max_id++;
} catch ( Exception ex ) {
#if DEBUG
Console.WriteLine( " ex=" + ex );
Console.WriteLine( " i=" + i + "; spl2[0]=" + spl2[0] + "; spl2[1]=" + spl2[1] );
#endif
}
}
}
}
/// <summary>
/// このVsqBPListの同一コピーを作成します
/// </summary>
/// <returns></returns>
public object Clone() {
VsqBPList res = new VsqBPList( Default, Minimum, Maximum );
foreach ( int key in m_list.Keys ) {
res.m_list.Add( key, m_list[key] );
}
return res;
}
/// <summary>
/// コンストラクタ。デフォルト値はココで指定する。
/// </summary>
/// <param name="default_value"></param>
public VsqBPList( int default_value, int minimum, int maximum ) {
Default = default_value;
Maximum = maximum;
Minimum = minimum;
m_max_id = 0;
}
/// <summary>
/// このリストに設定された最大値を取得します。
/// </summary>
public int getMaximum() {
return Maximum;
}
/// <summary>
/// このリストに設定された最小値を取得します
/// </summary>
public int getMinimum() {
return Minimum;
}
public Iterator keyClockIterator() {
return new KeyClockIterator( m_list );
}
public void remove( int clock ) {
if ( m_list.ContainsKey( clock ) ) {
m_list.Remove( clock );
}
}
public bool isContainsKey( int clock ) {
return m_list.ContainsKey( clock );
}
public int getCount() {
return m_list.Count;
}
public int[] getKeys() {
List<int> t = new List<int>();
foreach( int key in m_list.Keys ){
t.Add( key );
}
return t.ToArray();
}
public void clear() {
m_list.Clear();
}
/// <summary>
/// 新しいデータ点を追加します。
/// </summary>
/// <param name="clock"></param>
/// <param name="value"></param>
public void add( int clock, int value ) {
lock ( m_list ) {
if ( m_list.ContainsKey( clock ) ) {
VsqBPPair v = m_list[clock];
v.value = value;
m_list[clock] = v;
} else {
VsqBPPair v = new VsqBPPair( value, m_max_id + 1 );
m_max_id++;
m_list.Add( clock, v );
}
}
}
public int getElement( int index ) {
return m_list[m_list.Keys[index]].value;
}
public int getKeyClock( int index ) {
return m_list.Keys[index];
}
public int findValueFromID( int id ) {
int c = m_list.Keys.Count;
foreach ( int key in m_list.Keys ) {
if ( m_list[key].id == id ) {
return m_list[key].value;
}
}
return Default;
}
public void setValueForID( int id, int value ) {
int c = m_list.Keys.Count;
foreach ( int key in m_list.Keys ) {
if ( m_list[key].id == id ) {
VsqBPPair v = m_list[key];
v.value = value;
m_list[key] = v;
break;
}
}
}
public int getValue( int clock, ref int index ) {
if ( m_list.Count == 0 ) {
return Default;
} else {
if ( index < 0 ) {
index = 0;
}
for ( int i = index ; i < m_list.Keys.Count; i++ ) {
int keyclock = m_list.Keys[i];
if ( clock < keyclock ) {
if ( i > 0 ) {
index = i;
return m_list[m_list.Keys[i - 1]].value;
} else {
index = i;
return Default;
}
}
}
index = m_list.Keys.Count - 1;
return m_list[m_list.Keys[m_list.Keys.Count - 1]].value;
}
}
public int getValue( int clock ) {
if ( m_list.Count == 0 ) {
return Default;
} else {
for ( int i = 0; i < m_list.Keys.Count; i++ ) {
int keyclock = m_list.Keys[i];
if ( clock < keyclock ) {
if ( i > 0 ) {
return m_list[m_list.Keys[i - 1]].value;
} else {
return Default;
}
}
}
return m_list[m_list.Keys[m_list.Keys.Count - 1]].value;
}
}
/// <summary>
/// このBPListのデフォルト値を取得します
/// </summary>
public int getDefault() {
return Default;
}
/// <summary>
/// このBPListの内容をテキストファイルに書き出します
/// </summary>
/// <param name="writer"></param>
public void print( StreamWriter writer ) {
bool first = true;
foreach ( int key in m_list.Keys ) {
int val = m_list[key].value;
if ( first ) {
writer.WriteLine( key + "=" + val );
first = false;
} else {
writer.WriteLine( key + "=" + val );
}
}
}
/// <summary>
/// このBPListの内容をテキストファイルに書き出します
/// </summary>
/// <param name="writer"></param>
public void print( TextMemoryStream writer, int start, string header ) {
bool first = true;
foreach ( int key in m_list.Keys ) {
if ( start <= key ) {
if ( first ) {
writer.writeLine( header );
first = false;
}
int val = m_list[key].value;
writer.writeLine( key + "=" + val );
}
}
}
/// <summary>
/// テキストファイルからデータ点を読込み、現在のリストに追加します
/// </summary>
/// <param name="reader"></param>
/// <returns></returns>
public string appendFromText( TextMemoryStream reader ) {
string last_line = reader.readLine();
while ( !last_line.StartsWith( "[" ) ) {
string[] spl = last_line.Split( new char[] { '=' } );
int i1 = int.Parse( spl[0] );
int i2 = int.Parse( spl[1] );
VsqBPPair v = new VsqBPPair( i2, m_max_id + 1 );
m_max_id++;
m_list.Add( i1, v );
if ( reader.peek() < 0 ) {
break;
} else {
last_line = reader.readLine();
}
}
return last_line;
}
}
}