public void Переписать(АМОбъект примитив, int адрес) // существует опасность перекрытия данных { Писатель.BaseStream.Position = адрес; примитив.СохранисьВ(Писатель.BaseStream); Писатель.BaseStream.Position = адресСчетчика; СчетчикОбъетов++; Писатель.Write(СчетчикОбъетов); }
public override АМОбъект ПередайСообщениеСОтветом(АМОбъект сообщение) { if (АдресВКучеУдаленнаяСвязь == null) { УстановитьСвязь(); } var ответ = АдресВКучеУдаленнаяСвязь.ПолучиСообщениеСОтветом(сообщение.Копировать()); return(ответ); }
public АМОбъект ДайОбъектПоИндексу(int номер) { ЧитательИндекса.BaseStream.Position = номер * 4; var адресОбъекта = ЧитательИндекса.ReadInt32(); Читатель.BaseStream.Position = адресОбъекта; var прим = АМОбъект.Создать(Читатель.BaseStream); return(прим); }
public void ДобавитПрямуюСвязь(МягкаяСвязь новаяСвязь, АМОбъект имяОбранойСвязи) { ПрямыеСвязи.Add(новаяСвязь); dynamic объектПрямойСвязи = новаяСвязь.АдресОбъекта.АдресВКучеПамяти(); объектПрямойСвязи.ДобавитьОбратнуюСвязь(new МягкаяСвязь() { АдресОбъекта = СобственныйАдрес, ИмяСвязи = имяОбранойСвязи }); }
// можно создать разреженный объект поток и распихать его в дыры public MemoryStream ЗаписатьВВиртуальныйПоток(АМОбъект примитив) // { var виртПоток = new MemoryStream(); var писатель = new BinaryWriter(виртПоток); var кодТипа = Хранилище.кодыТипов[примитив.GetType()]; писатель.Write(кодТипа); примитив.СохранисьВ(Писатель); return(виртПоток); }
private void ОбработкаКоманды(АМОбъект сообщение) // это получи собщение с ответом { var команда = сообщение as Команда; ТекущийНомерКоманды = (ЦелоеЧисло)команда.Параметры[0]; var команда2 = команда.Параметры[1] as Команда; езультатТекущейКоманды = однаяАктивность.ВыполнитьКоманду(команда2); //РезультатТекущейКоманды = РоднаяАктивность.ПолучиСообщениеСОтветом(this,команда2); //команда может не иметь ответа т.е. будет Пустота лучше состояниеПриема = "идет передача ответа"; }
public override void ПолучиСообщение(Связь связь, АМОбъект сообщение) { // считает такты текущий++; ОтослатьСообщениеВсемИсходящим(текущий); if (текущий == 10) { СброситьСчетчик(); } }
public static АдресВХранилище Добавить(АМОбъект объект) { var номер = Память.Count; объект.СобственныйАдресПримитива = new АдресВХранилище() { НомерВХранилище = номер }; Память.Add(объект); return((АдресВХранилище)объект.СобственныйАдресПримитива); }
public override void ПолучиСообщение(Связь связь, АМОбъект сообщение) // это вариант с подпиской связь это представитель некоторой удалееной активности можно общаться с образом Активности { var индексСвязи = ((АдресВАктивности)связь.СобственныйАдресПримитива).номер; _Слогаемое[индексСвязи] = (ЦелоеЧисло)сообщение; if (_Слогаемое[0] != null && _Слогаемое[1] != null) { Сумма.Значение = _Слогаемое[0].Значение + _Слогаемое[0].Значение; // автоматическое срабатывание ОтослатьСообщениеВсемИсходящим(Сумма); } }
//команды от Активности public override void ПередайСообщение(АМОбъект сообщение) { if (АдресВКучеУдаленнаяСвязь == null) { УстановитьСвязь(); } if (АдресВКучеУдаленнаяСвязь != null) { var копияСообщения = сообщение; // модифицируется сообщение , можно добавить сообщение = null; АдресВКучеУдаленнаяСвязь.ПолучиСообщение(копияСообщения); } }
public void ИзменитьИзнутри(АМОбъект новоеЗначение) { Примитив = новоеЗначение; // сообщить об Изменении группе // найти связь с ролью хранитель или посредник хранителя var связь = АдресПримитива.СоздатьСвязь(); // это для активностей связь.ПередайСообщениеСОтветом(новоеЗначение); var группа = (ГруппаОбъектов)АдресПримитива.АдресРегистратора.АдресВКучеПамяти(); группа.Заменить(АдресПримитива, новоеЗначение); }
private void ОбработкаОтветНаКоманду(АМОбъект сообщение) { var команда = сообщение as Команда; // это ответ var номерКоманды = команда.Параметры[0]; // номер команды на которую дается ответ var ответ = команда.Параметры[1]; // найти команду в истории по номеру // добавить ответ к команде // сообщить Активности о приходе ответа или запустить привязаную реакцию однаяАктивность.ПолучиСообщение(this, ответ); состояниеПриема = "окончание сеанса"; }
public void ДобавитьИСохранить(АМОбъект примитивИлиАдрес) // в конец { Память.Add(примитивИлиАдрес); Писатель.Seek(0, SeekOrigin.End); var кодТипа = кодыТипов[примитивИлиАдрес.GetType()]; Писатель.Write(кодТипа); примитивИлиАдрес.СохранисьВ(Писатель); длинаФайла = (int)Писатель.BaseStream.Position; // = + длинаАдреса + длина списка }
private void ОбработкаСлужебнойКоманды(АМОбъект сообщение) { var команда = сообщение as Команда; if (команда.НомерКоманды.Значение == 1 || команда.Имя.Значение == "прямая передача") { МетодПриемаСообщения = ПрямаяПередачаВАктивностьСОтветами; состояниеПриема = "начат прием сообщения"; return; } if (команда.НомерКоманды.Значение == 5 || команда.Имя.Значение == "конец связи") { состояниеПриема = "окончание сеанса"; return; } }
public override АМОбъект Восстановить(BinaryReader читатель) //востановить объект без значения из потока Хранилища { var объект = base.Восстановить(читатель); // создать пустой объект экземпляр по адресу из справочника типов Хранилища // востановить адрес дискового хранилища ЦелоеНаДиске = (ЦелоеНаДиске)АМОбъект.Создать(читатель.BaseStream); //восстановить адрес в сети Слушатель = (ТСПСвязьВходящая)АМОбъект.Создать(читатель.BaseStream); Старт(); return(this); }
public АдресВФайле ДобавитьВКонец(АМОбъект примитив) //добавить в конец файла { var адресБайта = (int)Писатель.BaseStream.Length; Переписать(примитив, адресБайта); //установить указатель в конец и записать ПисательИндекса.BaseStream.Position = ПисательИндекса.BaseStream.Length; ПисательИндекса.Write(адресБайта); // номер объекта по индексу* 4 = содержит return(new АдресВФайле() { НомерБайтаВФайле = адресБайта, СобственныйАдресПримитива = this.СобственныйАдресПримитива }); }
public АМОбъект СоздатьКопиюОбъект(Адрес адрес) //читает только первый уровень, не лезет разбирать адреса { var фАдрес = адрес as АдресВФайле; if (фАдрес == null) { return(Пустота.Статик); } Читатель.BaseStream.Position = фАдрес.НомерБайтаВФайле; //перместить указатель на адрес объекта var прим = АМОбъект.Создать(Читатель.BaseStream); return(прим); }
// добавить исходящие public override void ПолучиСообщение(Связь связь, АМОбъект сообщение) { var сообщВнутр = сообщение as Сообщение; int последний = СписокКомуОтдать.Список.Count; var адресСвязи = ((АдресВАктивности)связь.СобственныйАдресПримитива).номер; //Исключение эффекта эха for (int i = 0; i < адресСвязи; i++) { ((Связь)СписокКомуОтдать.Список[i]).ПередайСообщение(сообщВнутр); } for (int i = адресСвязи + 1; i < последний; i++) { ((Связь)СписокКомуОтдать.Список[i]).ПередайСообщение(сообщВнутр); } }
public override АМОбъект Восстановить(BinaryReader читатель) { var длина = читатель.ReadInt32(); for (int i = 0; i < длина; i++) { var номерТипа = читатель.ReadByte(); var тип = Хранилище.Типы[номерТипа]; var k = тип.GetConstructor(Type.EmptyTypes); АМОбъект ключ = ( АМОбъект)k.Invoke(null); ключ.Восстановить(читатель); номерТипа = читатель.ReadByte(); тип = Хранилище.Типы[номерТипа]; k = тип.GetConstructor(Type.EmptyTypes); АМОбъект значение = ( АМОбъект)k.Invoke(null); значение.Восстановить(читатель); Добавить(ключ, значение); } return(this); }
public void НаОбъектПоИндексу(int индекс, АМОбъект объект) { ЧитательИндекса.BaseStream.Position = индекс * 4; var адресОбъекта = ЧитательИндекса.ReadInt32(); Читатель.BaseStream.Position = адресОбъекта; int длинаОбъекта; длинаОбъекта = ЧитательИндекса.ReadInt32(); // вариант с записью длины в индекс // узнать длину сохраненного объекта, его тип var номерТипа = Читатель.ReadByte(); var тип = Хранилище.Типы[номерТипа]; // для примитивов длинаОбъекта = (int)тип.InvokeMember("Длина", BindingFlags.InvokeMethod, null, null, null); //для групп и строк длинаОбъекта = Читатель.ReadUInt16(); // если тип объекта совпадает с типом сохраненного объекта и этот тип не группа = длины сохраненных объектов совпадают Переписать(объект, адресОбъекта); // если ттип не совпадает // то сравнить длину , если длина совпадает, то ттоже записать // если длина не совпадает //то найти подходящее место // в файле с удалениями есть // запомниттьпустое место int новыйАдресОбъекта = 0; // запомнить новый адрес в индексе ЧитательИндекса.BaseStream.Position = индекс * 4; ПисательИндекса.Write(новыйАдресОбъекта); Переписать(объект, новыйАдресОбъекта); // записать в удаленных пусттое место адрес начала, длина, было бы не плохо отсортировать этот файл по длинам // еще вариант использовать }
public static void ВосстановитьПамятьПоИндексу() { Читатель.ReadString(); //=хранилище длинаАдреса = Читатель.ReadByte(); //длинаАдреса var активности = new List <Активность>(); //запускаемые объекты for (int и = 0; и < ИндексВпамяти.Count; и++) { Читатель.BaseStream.Position = ИндексВпамяти[и]; var номерТипа = Читатель.ReadByte(); var тип = Типы[номерТипа]; var k = тип.GetConstructor(Type.EmptyTypes); АМОбъект примитив = ( АМОбъект)k.Invoke(null); примитив.Восстановить(Читатель); примитив.СобственныйАдресПримитива = new АдресВХранилище() { НомерВХранилище = и }; //примитив.НомерВФайле = ИндексВпамяти[и]; //этот номер доступен по Индексу Хранилища Память.Add(примитив); if (примитив is Активность) { активности.Add((Активность)примитив); } } foreach (var активность in активности) { try { активность.Запуск(); } catch (Exception) { } } }
public static void ВосстановитьПамять() { Читатель.ReadString(); //=хранилище длинаАдреса = Читатель.ReadByte(); //длинаАдреса var активности = new List <Активность>(); //запускаемые объекты while (Читатель.BaseStream.Length > Читатель.BaseStream.Position) { var номерТипа = Читатель.ReadByte(); var тип = Типы[номерТипа]; //var p = new object[0]; var k = тип.GetConstructor(Type.EmptyTypes); АМОбъект примитив = ( АМОбъект)k.Invoke(null); примитив.Восстановить(Читатель); //.InvokeMember("Восстановить",BindingFlags.InvokeMethod, null,null,new []{Читатель}); примитив.СобственныйАдресПримитива = new АдресВХранилище() { НомерВХранилище = Память.Count }; Память.Add(примитив); if (примитив is Активность) { активности.Add((Активность)примитив); } } // цикл запуска активностей foreach (var активность in активности) { try { активность.Запуск(); } catch (Exception) { } } }
private int разрешенныйОтступ; //= Разрешенная пауза не сбрасывает счетчик, пока не поступит это количество пустых тактов // так можно реализовать отслеживание перестановки букв public override void ПолучиСообщение(Связь связь, АМОбъект сообщение) // это сообщение посылает либо активность представляющая ее части, либо пустой такт { var поступившаяАктивность = сообщение as Активность; // если поступившая есть в списке и она еще неприходила if (СписокАктивностей.Contains(поступившаяАктивность)) { if (!ПришедшиеАктивности.Contains(поступившаяАктивность)) // если она ранее не приходила { ПришедшиеАктивности.Add(поступившаяАктивность); if (ПришедшиеАктивности.Count == СписокОтКогоПолучить.Список.Count) { ОтослатьСообщениеВсемИсходящим("все пришли"); ПришедшиеАктивности.Clear(); } } else // если уже ранее приходила //если придет два раза "русская" (дребезг) { //если текущий пауза меньше разрешенной // вариант 1 устранение дребезга = "одна или несколько одинаковвых слов //ничего не делать //вариант 2 точное совпадение, не допускаются повторы ПришедшиеАктивности.Clear(); } } else //если пришла неподходящая активность - пустой такт { //если текущий пауза меньше разрешенной ПришедшиеАктивности.Clear(); } //if (поступившаяАктивность != null) //если это не пустой такт //{ //} }
//тоже можно сделать по номеру поля а не имени public static АМОбъект НаЗначение(ГруппаОбъектов экземпляр, string имяПоля, АМОбъект значение) { var класс = (ГруппаОбъектов)экземпляр[0]; var типЭкземпляраЗначения = ((ГруппаОбъектов)значение)[0]; //значение предполагается что это экземпляр класса var имяТипа = ((ГруппаОбъектов)типЭкземпляраЗначения)[1]; for (int i = 1; i < ((ГруппаОбъектов)класс[2]).Список.Count; i++) { if (((СтрокаЮникода)((ГруппаОбъектов)((ГруппаОбъектов)класс[2])[i])[1]).Значение == имяПоля) { // можно добавить прроверку типа значения и поля, значение должно быть экземпляром // порверку типа можно исключить для откопмелированого кода var ТипПоля = ((ГруппаОбъектов)((ГруппаОбъектов)класс[2])[i])[2]; if (типЭкземпляраЗначения == ТипПоля) { экземпляр[i] = значение; return(new СтрокаЮникода("Готово")); } return(new СтрокаЮникода("Несовпадение типов поля и значения")); } } return(new СтрокаЮникода("Нет такого имени поля")); }
public virtual void ПередайСообщение(АМОбъект сообщение) //это поток активности , ответ не предполагется { try { //если отправлять сообщения разрешено,то // перед запуском отправки нужно проверить занато соединение или нет, можно отдать эту логику активности if (Канал.СоединениеУстановлено) { var команда = new Команда("Сообщение", сообщение) { НомерКоманды = new ЦелоеЧисло(0) }; // если поток не занят , то установить что поток занят - одновременно получать и передавать команды нельзя, лучше сделать два встречных соединения Канал.ПередайИсходящееСообщение(команда); //перейти в ожидание ответа //var ответ = Канал.ДайВходящееСообщение();// отвкт Пустота как подтверждение } } catch (Exception) { Канал.СоединениеУстановлено = false; // } }
public override АМОбъект Восстановить(BinaryReader читатель) { АдресРегистратора = (Адрес)АМОбъект.Создать(читатель.BaseStream); НомерВГруппе = читатель.ReadInt32(); return(this); }
public virtual Адрес Добавить(АМОбъект объект) { return(null); }
public override void ПолучиСообщение(Связь связь, АМОбъект сообщение) { // если сообщение просто символ или адрес объекта if (Множество.Contains(сообщение)) { return; } Множество.Add(сообщение); // если получаются сообщения интерактивно по одному символу var объект = сообщение; if (объект == null) // сигнал завершения { if (_режимДобавления) { //событие добавлен новый список объектов МножествоСписков.Add(ТекущийОбъектСписок); //если список отсортирован, можно вставить в нужное место ОтослатьСообщениеВсемИсходящим(ТекущийОбъектСписок); // отправиться только адрес } else { // у нас есть список подходящих, объект с совпадающей длиной и есть совпадение ( в отсортированном должен быть первым элементом) var длинаОбъекта = ТекущийОбъектСписок.Count; var номерПодходящего = -1; for (int i = 0; i < СписокПодходящихОбъектов.Count; i++) { if (длинаОбъекта == СписокПодходящихОбъектов[i].Count) { номерПодходящего = i; ТекущийОбъектСписок = СписокПодходящихОбъектов[i]; // событие найден подходящий объект - т.е. список реакций не пустой ОтослатьСообщениеВсемИсходящим(СписокПодходящихОбъектов[i]); break; // обнулить все и выйти } } if (номерПодходящего == -1) //все подходящие длиннее { МножествоСписков.Add(ТекущийОбъектСписок); //если список отсортирован, можно вставить в нужное место //событие добавлен новый список объектов ОтослатьСообщениеВсемИсходящим(ТекущийОбъектСписок); } } _режимДобавления = false; ТекущийИндекс = 0; СписокПодходящихОбъектов = null; ТекущийОбъектСписок = null; return; } if (ТекущийИндекс == 0) { СписокПодходящихОбъектов = МножествоСписков; ТекущийОбъектСписок = new ИменованнаяГруппа2() { ИмяГруппы = "Имя Этого Словаря" }; } ТекущийОбъектСписок.Add(объект); if (!_режимДобавления) { СписокПодходящихОбъектов = НайтиПодходящиеПоТекущемуИндексу(объект); if (СписокПодходящихОбъектов.Count == 0) //нет ни одного подхлдящего - сброс поиска { _режимДобавления = true; //повторить поиск для нуля Это для поиска подстроки } // посыл промежуточных результатов ОтослатьСообщениеВсемИсходящим(СписокПодходящихОбъектов);// если режим добавления запрещен и подходящий только 1 можно предположить что набираемый список именно этот } }
public void ПередайСообщениеВПоток(АМОбъект сообщение) { сообщение.СохранисьВ(поток); }
public void АссинхроннаяОбработка(NetworkStream поток) // параллельно может идти запись { // var объект = АМОбъект.Создать(поток); // связь может застрять посредине чтения , если зависание больше нормы разорвать соединение // необходима синхронизация обработки данных }