OSDN Git Service

add undo/redo system
[eliscolors/main.git] / ElisKeyframe.m
1 //  Copyright (c) 2009 Yanagi Asakura
2 //
3 //  This software is provided 'as-is', without any express or implied
4 //  warranty. In no event will the authors be held liable for any damages
5 //  arising from the use of this software.
6 //
7 //  Permission is granted to anyone to use this software for any purpose,
8 //  including commercial applications, and to alter it and redistribute it
9 //  freely, subject to the following restrictions:
10 //
11 //  1. The origin of this software must not be misrepresented; you must not
12 //  claim that you wrote the original software. If you use this software
13 //  in a product, an acknowledgment in the product documentation would be
14 //  appreciated but is not required.
15 //
16 //  2. Altered source versions must be plainly marked as such, and must not be
17 //  misrepresented as being the original software.
18 //
19 //  3. This notice may not be removed or altered from any source
20 //  distribution.
21
22 //
23 //  ElisKeyframe.m
24 //  Elis Colors
25 //
26 //  Created by 柳 on 09/09/15.
27 //  Copyright 2009 __MyCompanyName__. All rights reserved.
28 //
29
30 #import "ElisKeyframe.h"
31
32 static float convertQTTimeToSecond(QTTime t)
33 {
34     return (float)t.timeValue/t.timeScale;
35 }
36
37 @implementation ElisKeyframe
38
39 - (id)init
40 {
41     [super init];
42     timesAndValues = [[NSMutableDictionary alloc] init];
43     cacheTime = NAN;
44     return self;
45 }
46
47 - (void)setValueForTime:(float)value time:(QTTime)time
48 {
49     int i, j;
50     long long tmp1, tmp2;
51     
52     [timesAndValues setObject:[NSNumber numberWithFloat:value] forKey:[NSNumber numberWithFloat:convertQTTimeToSecond(time)]];
53     sortedTimes = [[timesAndValues allKeys] sortedArrayUsingSelector:@selector(compare:)];
54     // 常識的に考えて、NSArrayである必要なくね? Cの配列でよくね?
55     
56     cacheTime = NAN;
57     
58 // Cの配列時代の実装。挿入ソート?
59 //    for(i = 0; i < index-1; i++){
60 //        if(times[i].timeValue == time.timeValue){
61 //            values[i] = value;
62 //            return;
63 //        }
64 //        if(times[i].timeValue <= time.timeValue && time.timeValue <= times[i+1].timeValue){
65 //            for(j = index; j > i+1; j--){
66 //                times[j] = times[j-1];
67 //                values[j] = values[j-1];
68 //            }
69 //            times[i+1] = time;
70 //            values[i+1] = value;
71 //            return;
72 //        }
73 //    }
74 //    if(times[index-1].timeValue == time.timeValue) values[index-1] = value;
75 //    else if(times[index-1].timeValue <= time.timeValue){
76 //        times[index] = time;
77 //        values[index++] = value; 
78 //    }else{
79 //        times[index] = times[index-1];
80 //        values[index] = values[index-1];
81 //        times[index-1] = time;
82 //        values[index-1] = value;
83 //        index++;
84 //    }
85 //    return;
86 }
87
88 // いろいろすさまじい。ボトルネックになりそうだなあここ。
89 // 描画を実行する度に2回呼ばれる。キャッシュするか。
90 - (float)getValueForTime:(QTTime)time
91 {
92 //    long long now = time.timeValue;
93 //    int i;
94 //    for(i = 0; i < index-1; i++){
95 //        if(times[i].timeValue <= now && now <= times[i+1].timeValue){
96 //            return ((float)(times[i+1].timeValue - now) * values[i] +
97 //                    (float)(now - times[i].timeValue) * values[i+1])/(times[i+1].timeValue - times[i].timeValue);
98 //        }
99 //    }
100 //    if(now <= times[0].timeValue) return values[0];
101 //    if(times[index-1].timeValue <= now) return values[index-1];
102     float now = convertQTTimeToSecond(time);
103     
104     if(cacheTime == now) return cacheValue;
105     cacheTime = now;
106     
107     int i, size = [sortedTimes count];
108     
109     if(size == 1){
110         cacheValue = [[timesAndValues objectForKey:[sortedTimes objectAtIndex:0]] floatValue];
111         return cacheValue;
112     }
113     
114     if([[sortedTimes lastObject] floatValue] <= now){
115         cacheValue = [[timesAndValues objectForKey:[sortedTimes lastObject]] floatValue];
116         return cacheValue;
117     }
118     
119     for(i = 0; i < size-1; i++){
120         if([[sortedTimes objectAtIndex:i] floatValue] <= now &&
121            now <= [[sortedTimes objectAtIndex:i+1] floatValue]){
122             cacheValue = (([[sortedTimes objectAtIndex:i+1] floatValue] - now) * 
123                 [[timesAndValues objectForKey:[sortedTimes objectAtIndex:i]] floatValue] +
124                 (now - [[sortedTimes objectAtIndex:i] floatValue]) * 
125                 [[timesAndValues objectForKey:[sortedTimes objectAtIndex:i+1]] floatValue]) /
126             ([[sortedTimes objectAtIndex:i+1] floatValue] - [[sortedTimes objectAtIndex:i] floatValue]);
127             return cacheValue;
128         }
129     }
130
131
132     return cacheValue;
133 }
134
135 - (void)encodeWithCoder:(NSCoder*)encoder
136 {
137     [encoder encodeObject:timesAndValues forKey:@"timesAndValues"];
138     [encoder encodeObject:sortedTimes forKey:@"sortedTimes"];
139 }
140
141 - (id)initWithCoder:(NSCoder*)coder
142 {
143     timesAndValues = [coder decodeObjectForKey:@"timesAndValues"];
144     sortedTimes = [coder decodeObjectForKey:@"sortedTimes"];
145     cacheTime = NAN;
146     
147     return self;
148 }
149
150 @end