Архив рубрики "программирование"

22
Фев

trac

   Автор: Aen Sidhe

Воткнул Trac на флешку. Довольно удобно.

Метки:issue tracking, программирование
15
Фев

issue tracker

   Автор: Aen Sidhe

Товарищи программисты, если у вас есть солопроекты, то в чём вы ведёте учёт багов и прочего? Выкладывать исходники на публику не планирую, результаты – планирую.

Метки:issue tracking, программирование
9
Фев

hosting

   Автор: Aen Sidhe

А вот почему я хочу хостинг территориально в РФ:

Т.е. если мы используем любые криптоалгоритмы (ну, например, MD5 или CRC32 для подсчёта контрольных сумм файлов) и пытаемся хоститься на code.google.com или sourceforge.net, то надо либо согласиться с ограничениями на экспорт технологий из США, либо исключить эти технологии из проекта.

Пока данные ограничения есть только на этих двух сайтах, афаик.

Потырено с хабра.

UPD: самое смешное, что под это попадает весь софт под платформу .NET, ибо сборки от МС имеют strong name, т.е. цифровую подпись, т.е. в проекте используется криптография.

Метки:hosting, политика, программирование
15
Янв

TBlogger strikes back

   Автор: Aen Sidhe

Первый, тестовый пост с моего варианта мобильного клиента для WordPress|MetaBlog.

Метки:дневник, программирование
22
Дек

simple test 2

   Автор: Aen Sidhe

Код в предыдущей записи действительно смахивает на WTF, но он таким, имхо, не является.

Итак, задание – сделать конфигурируемый планировщик, позволяющий:

  1. Иметь сколько угодно заданий
  2. Имеющий заданную точность (у нас 5 секунд)
  3. Конфигурация должна спокойно производится человеком, не имеющим технического образования и опыта программирования.
  4. Каждое событие должно иметь следующие признаки:
    1. Время запуска
    2. Количество срабатываний (как конечное, так и нет)
    3. Интервал запуска
    4. Возможность разрешить или запретить запуск в любой из дней недели или день года, т.е. события только на 31.12 или только по вторникам, или наоборот в любой день, кроме вторников – реальность.

Исходя из этого, было придумано то, что видно в записи по линку выше. Сериализуется это (класс был переименован в Period) вот в такой xml:

<Period>
    <EnabledDaysOfWeek>Monday Tuesday Wednesday Thursday Friday Saturday Sunday</EnabledDaysOfWeek>
    <EnabledMonthes>January February March April May Juny July August September October November December</EnabledMonthes>
    <EnabledDays>d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31</EnabledDays>
    <Count xsi:nil="true" />
    <StartTime>16:00:00</StartTime>
    <Interval>1.00:00:00</Interval>
</Period>

Соответственно, просто пишем через пробел нужные нам дни недели/месяцы/дни и радуемся жизни.

Вопрос: как сделать лучше, не ухудшая читабельность конфига? Конфиг необязательно, но желательно, должен быть xml.

Метки:программирование
21
Дек

simple test

   Автор: Aen Sidhe

Мелкий тест.

Ниже длинный исходник на C#. Определить – WTF он или нет и предположить, зачем он нужен. Завтра выложу полный исходник с объяснениями.

    [Flags]
    public enum Month
    {
        January   = 0x1,
        February  = 0x2,
        March     = 0x4,
        April     = 0x8,
        May       = 0x10,
        Juny      = 0x20,
        July      = 0x40,
        August    = 0x80,
        September = 0x100,
        October   = 0x200,
        November  = 0x400,
        December  = 0x800,
    }

    [Flags]
    public enum FlaggingDayOfWeek
    {
        Monday    = 0x1,
        Tuesday   = 0x2,
        Wednesday = 0x4,
        Thursday  = 0x8,
        Friday    = 0x10,
        Saturday  = 0x20,
        Sunday    = 0x40,
    }

    [Flags]
    public enum Days
    {
        d1 = 0x1,
        d2 = 0x2,
        d3 = 0x4,
        d4 = 0x8,
        d5 = 0x10,
        d6 = 0x20,
        d7 = 0x40,
        d8 = 0x80,
        d9 = 0x100,
        d10 = 0x200,
        d11 = 0x400,
        d12 = 0x800,
        d13 = 0x1000,
        d14 = 0x2000,
        d15 = 0x4000,
        d16 = 0x8000,
        d17 = 0x10000,
        d18 = 0x20000,
        d19 = 0x40000,
        d20 = 0x80000,
        d21 = 0x100000,
        d22 = 0x200000,
        d23 = 0x400000,
        d24 = 0x800000,
        d25 = 0x1000000,
        d26 = 0x2000000,
        d27 = 0x4000000,
        d28 = 0x8000000,
        d29 = 0x10000000,
        d30 = 0x20000000,
        d31 = 0x40000000,
    }

    public class Schedule
    {
        #region Cache

        public const FlaggingDayOfWeek AllDaysOfWeek = FlaggingDayOfWeek.Monday | FlaggingDayOfWeek.Tuesday |
            FlaggingDayOfWeek.Wednesday | FlaggingDayOfWeek.Thursday | FlaggingDayOfWeek.Friday |
            FlaggingDayOfWeek.Saturday | FlaggingDayOfWeek.Sunday;

        public const Month AllMonthes =
            Month.January | Month.February | Month.March |
            Month.April | Month.May | Month.Juny |
            Month.July | Month.August | Month.September |
            Month.October | Month.November | Month.December;

        public const Days AllDays =
            Days.d1 | Days.d2 | Days.d3 | Days.d4 | Days.d5 | Days.d6 | Days.d7 |
            Days.d8 | Days.d9 | Days.d10 | Days.d11 | Days.d12 | Days.d13 | Days.d14 |
            Days.d15 | Days.d16 | Days.d17 | Days.d18 | Days.d19 | Days.d20 | Days.d21 |
            Days.d22 | Days.d23 | Days.d24 | Days.d25 | Days.d26 | Days.d27 | Days.d28 |
            Days.d29 | Days.d30 | Days.d31;

        private static readonly Dictionary<DayOfWeek, FlaggingDayOfWeek> m_DaysOfWeekCache = new Dictionary<DayOfWeek, FlaggingDayOfWeek>
        {
            { DayOfWeek.Monday, FlaggingDayOfWeek.Monday },
            { DayOfWeek.Tuesday, FlaggingDayOfWeek.Tuesday },
            { DayOfWeek.Wednesday, FlaggingDayOfWeek.Wednesday },
            { DayOfWeek.Thursday, FlaggingDayOfWeek.Thursday },
            { DayOfWeek.Friday, FlaggingDayOfWeek.Friday },
            { DayOfWeek.Saturday, FlaggingDayOfWeek.Saturday },
            { DayOfWeek.Sunday, FlaggingDayOfWeek.Sunday },
        };

        private static readonly Dictionary<int, Month> m_MonthesCache = new Dictionary<int, Month>
        {
            { 1, Month.January },
            { 2, Month.February },
            { 3, Month.March },
            { 4, Month.April },
            { 5, Month.May },
            { 6, Month.Juny },
            { 7, Month.July },
            { 8, Month.August },
            { 9, Month.September },
            { 10, Month.October },
            { 11, Month.November },
            { 12, Month.December },
        };

        private static readonly Dictionary<int, Days> m_DaysCache = new Dictionary<int, Days>
        {
            { 1, Days.d1 },
            { 2, Days.d2 },
            { 3, Days.d3 },
            { 4, Days.d4 },
            { 5, Days.d5 },
            { 6, Days.d6 },
            { 7, Days.d7 },
            { 8, Days.d8 },
            { 9, Days.d9 },
            { 10, Days.d10 },
            { 11, Days.d11 },
            { 12, Days.d12 },
            { 13, Days.d13 },
            { 14, Days.d14 },
            { 15, Days.d15 },
            { 16, Days.d16 },
            { 17, Days.d17 },
            { 18, Days.d18 },
            { 19, Days.d19 },
            { 20, Days.d20 },
            { 21, Days.d21 },
            { 22, Days.d22 },
            { 23, Days.d23 },
            { 24, Days.d24 },
            { 25, Days.d25 },
            { 26, Days.d26 },
            { 27, Days.d27 },
            { 28, Days.d28 },
            { 29, Days.d29 },
            { 30, Days.d30 },
            { 31, Days.d31 },
        };

        #endregion

        public FlaggingDayOfWeek EnabledDaysOfWeek { get; set; }

        public Month EnabledMonthes { get; set; }

        public Days EnabledDays { get; set; }

        [XmlIgnore]
        public TimeSpan StartTime { get; set; }

        [XmlIgnore]
        public TimeSpan Interval { get; set; }

        public int? Count { get; set; }

        [XmlElement(DataType = "duration", ElementName = "StartTime")]
        public string FakeStartTime
        {
            get { return StartTime.ToString(); }
            set { StartTime = TimeSpan.Parse(value); }
        }

        [XmlElement(DataType = "duration", ElementName = "Interval")]
        public string FakeInterval
        {
            get { return Interval.ToString(); }
            set { Interval = TimeSpan.Parse(value); }
        }
    }
Метки:программирование
16
Дек

perfomance

   Автор: Aen Sidhe

Будете смеяться, но после того, как я оптимизировал создание карты с 10 секунд до 23 миллисекунд, мы упёрлись в производительность стандартных коллекций.

Раньше, когда небо было голубое и трава зелёная, монстров у нас было чётко заданное количество. Поэтому был массив. Сейчас, количество мобов меняется, поэтому, недолго думая, был всунут List<T>. Всё бы ничего, но сервер тут же стал жрать в 4 раза больше проца. Замеры показали, что почти вся нагрузка – пересчёт монстров, из которого половину времени мы сидим в геттера List<T>.Item.

Думаем, что делать :)

Метки:программирование, рабочее
3
Дек

Android

   Автор: Aen Sidhe

Наряду с мегаОС, гугло толкает свою платформу на мобильные устройства? Android. Успешно так толкает. Исследование среди разработчиков показывает успешность:

  • 57% не устраивает получаемый доход.
  • 90% сообщили, что число загрузок их приложений не превышает 10000.
  • 43% считают, что «Google Checkout» тормозит продажи приложений и требуют упрощения системы платежей.
  • 82% не устраивает дизайн Android Market, так как он усложняет поиск старых и заметность новых приложений.
  • 46% уверены, что разнообразие версий Android на выпускаемых устройствах существенно усложнит разработку, по причине проблем совместимости.
  • 68% разработчиков сомневаются в целесообразности развития и поддержке своих Android-приложений.
Метки:android, google, программирование
30
Ноя

system.addin vs. generics

   Автор: Aen Sidhe

По какой-то малопонятной мне причине адаптеры нельзя наследовать от генерик-типов. Сволочи.

Метки:программирование

Грабли, как мне кажется, есть везде. В своё время, ни одна библиотека не прошла мимо меня в проект, кроме, пожалуй, Infragistics, без доработки. Поговорим о граблях в System.AddIn.

Для начала порекомендую прочитать статью в блоге Джейсона Хи (Jason He), которая называется «Coding patterns to avoid in addin pipeline development». Да и вообще, его блог почитать надо, он поподробнее Walkthrough в MSDN.

Итак, первая грабля, на которую я наступил: дефолтные домены работают без ShadowCopy, как следствие, заменить сборки на горячем сервере мы не можем. Ок, нам особо и не надо, сделаем домен сами:

AddInStore.Update(pipelineRootFolderPath);

Collection tokens = AddInStore.FindAddIns(typeof(IView), pipelineRootFolderPath);

AddInToken calcToken = tokens[0];

AppDomain domain = AppDomain.CreateDomain(string.Format("Test {0}", DateTime.Now), null, new AppDomainSetup { ShadowCopyFiles = "true" });

return calcToken.Activate(domain);

Затем мы работаем, всё ок. Для выгрузки аддона используем такой код: AddInController.GetAddInController(calc).Shutdown(). По идее всё хорошо, но есть одно но. Из-за того, что мы домен создали вручную, то автоматически инфраструктура System.AddIn его не выгрузит. Да, это может быть логично, но об этом нигде не написано.

Код ниже логичен, но будет падать, несмотря на то, что ссылка на домен у контроллера есть, и она живая. Просто разработчики посчитали, что раз AddIn отключен, то домен нам уже не нужен. Вообще, реализация AddInController’a с lock(this) и прочим меня ни разу не порадовала.

AddInController c = AddInController.GetAddInController(calc);
c.Shutdown();
AppDomain.Unload(c.AppDomain);

Правильный код вот такой:

AddInController c = AddInController.GetAddInController(calc);
AppDomain d = c.AppDomain;
c.Shutdown();
AppDomain.Unload(d);
Метки:дневник, программирование, рабочее
Страница 1 из 41234