/
ReferenceMakerAndTarget.cs
143 lines (127 loc) · 4.2 KB
/
ReferenceMakerAndTarget.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//
// Copyright 2012 Autodesk, Inc. All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk license
// agreement provided at the time of installation or download, or which
// otherwise accompanies this software in either electronic or hard copy form.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Max;
namespace MaxSharp
{
/// <summary>
/// Represents a scene element that can create references to other scene elements.
/// </summary>
public class ReferenceMaker : Animatable
{
internal ReferenceMaker( IReferenceMaker x) : base(x)
{
if (parameterBlock == null)
parameterBlock = Targets.FilterType<ParameterBlock2>().FirstOrDefault();
if (parameterBlock == null)
parameterBlock = Targets.FilterType<ParameterBlock1>().FirstOrDefault();
}
public IReferenceMaker _Maker { get { return _Anim as IReferenceMaker; } }
public IEnumerable<ReferenceTarget> Targets
{
get
{
for (int i = 0; i < _Maker.NumRefs; ++i)
{
if (_Maker.GetReference(i) != null)
{
ReferenceTarget rt = null;
try
{
rt = CreateWrapper<ReferenceTarget>(_Maker.GetReference(i));
}
catch (Exception)
{
// Happens because the EPhere wrapper can't handle all reference types.
}
if (rt != null)
yield return rt;
}
}
}
}
public IEnumerable<ReferenceTarget> TargetTree
{
get
{
foreach (ReferenceTarget rt in Targets)
{
foreach (ReferenceTarget rt2 in rt.TargetTree)
yield return rt2;
yield return rt;
}
}
}
/// <summary>
/// This is the number of references
/// </summary>
public int NumTargets
{
get { return _Maker.NumRefs; }
}
public ReferenceTarget GetTarget(int n)
{
return CreateWrapper<ReferenceTarget>(_Maker.GetReference(n));
}
public void SetTarget(int n, ReferenceTarget rt)
{
if (rt == null)
_Maker.ReplaceReference(n, null, true);
else
_Maker.ReplaceReference(n, rt._Target, true);
}
public IndexedProperty<int, ReferenceTarget> TargetArray
{
get
{
return new IndexedProperty<int, ReferenceTarget>(
(int n) => GetTarget(n),
(int n, ReferenceTarget rt) => SetTarget(n, rt));
}
}
}
/// <summary>
/// An iterator that allows the observers of a reference target to be enumerated.
/// </summary>
class ObserverIterator : Autodesk.Max.Plugins.DependentEnumProc
{
public List<ReferenceMaker> makers = new List<ReferenceMaker>();
public override int Proc( IReferenceMaker rmaker)
{
if (rmaker != null)
makers.Add(Animatable.CreateWrapper<ReferenceMaker>(rmaker));
return 0;
}
}
/// <summary>
/// Represents a scene element that can be notified of changes.
/// </summary>
public class ReferenceTarget : ReferenceMaker
{
internal ReferenceTarget(IReferenceTarget x) : base(x)
{
}
public IReferenceTarget _Target { get { return _Anim as IReferenceTarget; } }
public IEnumerable<ReferenceMaker> Observers
{
get
{
ObserverIterator o = new ObserverIterator();
_Target.DoEnumDependents(o);
return o.makers;
}
}
public void AddListener(Action a)
{
new ReferenceListener(this, RefMessage.Change, a);
}
}
}