1+ /*----------------------------------------------------------
2+ This Source Code Form is subject to the terms of the
3+ Mozilla Public License, v.2.0. If a copy of the MPL
4+ was not distributed with this file, You can obtain one
5+ at http://mozilla.org/MPL/2.0/.
6+ ----------------------------------------------------------*/
7+
8+ using System ;
9+ using System . Collections . Generic ;
10+ using System . Linq ;
11+ using OneScript . Contexts ;
12+ using OneScript . Types ;
13+ using ScriptEngine . Machine ;
14+ using ScriptEngine . Machine . Contexts ;
15+
16+ namespace OneScript . StandardLibrary . Collections
17+ {
18+ /// <summary>
19+ /// Класс Соответствие, который оборачивает произвольный Dictionary
20+ /// </summary>
21+ public class MapWrapper < TKey , TValue > : AutoCollectionContext < MapImpl , KeyAndValueImpl >
22+ {
23+ private readonly IDictionary < TKey , TValue > _originalMap ;
24+
25+ private static ContextMethodsMapper < MapWrapper < TKey , TValue > > _methods =
26+ new ContextMethodsMapper < MapWrapper < TKey , TValue > > ( ) ;
27+
28+ public static MapWrapper < TKey , TValue > Create ( ITypeManager typeManager , IDictionary < TKey , TValue > originalMap )
29+ {
30+ var type = typeManager . GetTypeByFrameworkType ( typeof ( MapImpl ) ) ;
31+ return new MapWrapper < TKey , TValue > ( type , originalMap ) ;
32+ }
33+
34+ private MapWrapper (
35+ TypeDescriptor mapType ,
36+ IDictionary < TKey , TValue > originalMap ) : base ( mapType )
37+ {
38+ _originalMap = originalMap ;
39+ }
40+
41+ public override bool IsIndexed => true ;
42+
43+ [ ContextMethod ( "Количество" , "Count" ) ]
44+ public override int Count ( ) => _originalMap . Count ;
45+
46+ public override IEnumerator < KeyAndValueImpl > GetEnumerator ( )
47+ {
48+ return _originalMap . Select ( entry => new KeyAndValueImpl (
49+ ContextValuesMarshaller . ConvertReturnValue ( entry . Key ) ,
50+ ContextValuesMarshaller . ConvertReturnValue ( entry . Value ) ) ) . GetEnumerator ( ) ;
51+ }
52+
53+ public override IValue GetIndexedValue ( IValue index )
54+ {
55+ if ( ! _originalMap . TryGetValue ( ContextValuesMarshaller . ConvertParam < TKey > ( index ) , out var mapValue ) )
56+ {
57+ return ValueFactory . Create ( ) ;
58+ }
59+
60+ return ContextValuesMarshaller . ConvertReturnValue ( mapValue ) ;
61+ }
62+
63+ public override void SetIndexedValue ( IValue index , IValue val )
64+ {
65+ if ( index . SystemType != BasicTypes . Undefined )
66+ {
67+ var mapKey = ContextValuesMarshaller . ConvertParam < TKey > ( index ) ;
68+ var mapVal = ContextValuesMarshaller . ConvertParam < TValue > ( val ) ;
69+ _originalMap [ mapKey ] = mapVal ;
70+ }
71+ }
72+
73+ public override bool IsPropReadable ( int propNum )
74+ {
75+ return false ;
76+ }
77+
78+ public override bool IsPropWritable ( int propNum )
79+ {
80+ return false ;
81+ }
82+
83+ [ ContextMethod ( "Вставить" , "Insert" ) ]
84+ public void Insert ( IValue key , IValue val = null )
85+ {
86+ SetIndexedValue ( key , val ?? ValueFactory . Create ( ) ) ;
87+ }
88+
89+ [ ContextMethod ( "Получить" , "Get" ) ]
90+ public IValue Retrieve ( IValue key )
91+ {
92+ return GetIndexedValue ( key ) ;
93+ }
94+
95+ [ ContextMethod ( "Очистить" , "Clear" ) ]
96+ public void Clear ( )
97+ {
98+ _originalMap . Clear ( ) ;
99+ }
100+
101+ [ ContextMethod ( "Удалить" , "Delete" ) ]
102+ public void Delete ( IValue key )
103+ {
104+ _originalMap . Remove ( ContextValuesMarshaller . ConvertParam < TKey > ( key ) ) ;
105+ }
106+
107+ public override int GetMethodNumber ( string name ) => _methods . FindMethod ( name ) ;
108+
109+ public override int GetMethodsCount ( ) => _methods . Count ;
110+
111+ public override BslMethodInfo GetMethodInfo ( int methodNumber ) => _methods . GetRuntimeMethod ( methodNumber ) ;
112+
113+ public override void CallAsProcedure ( int methodNumber , IValue [ ] arguments )
114+ {
115+ var binding = _methods . GetCallableDelegate ( methodNumber ) ;
116+ try
117+ {
118+ binding ( this , arguments ) ;
119+ }
120+ catch ( System . Reflection . TargetInvocationException e )
121+ {
122+ throw e . InnerException ! ;
123+ }
124+ }
125+
126+ public override void CallAsFunction ( int methodNumber , IValue [ ] arguments , out IValue retValue )
127+ {
128+ var binding = _methods . GetCallableDelegate ( methodNumber ) ;
129+ try
130+ {
131+ retValue = binding ( this , arguments ) ;
132+ }
133+ catch ( System . Reflection . TargetInvocationException e )
134+ {
135+ throw e . InnerException ! ;
136+ }
137+ }
138+ }
139+ }
0 commit comments