Введення в CVS Конспект першого дня дводенного курсу
по CVS h2>
Jim
Blandy p>
Для чого потрібен CVS? h2>
CVS
підтримує історію дерева каталогів з вихідним кодом, працюючи з послідовністю
змін. CVS маркує кожну зміну моментом часу, коли воно було
зроблено, і ім'ям користувача, які вчинили зміна. Зазвичай людина,
що зробив зміна, також надає текстовий опис причини, з
якої відбулася зміна. Озброївшись всією цією інформацією, CVS
відповідати на такі питання, як p>
Хто
скоїв дану зміну? p>
Коли
вони його зробили? p>
Навіщо
вони це зробили? p>
Які
ще зміни відбулися в той же самий час? p>
Як
використовувати CVS - перший начерк p>
Перед
обговоренням безлічі разнобразних термінів та ідей, давайте поглянемо на
основні команди CVS. p>
Налаштування вашого сховища h2>
CVS
зберігає всі зміни в цьому проекті в дереві каталогів, званому
"репозиторієм" (repository). Перед тим, як почати використовувати CVS,
вам необхідно налаштувати змінну середовища CVSROOT так, щоб вона вказувала на
каталог сховища. Той, хто відповідальний за управління конфігурацією вашого
проекту, ймовірно, знає, що саме повинна містити в собі ця змінна; можливо
навіть, що змінна CVSROOT вже встановлена глобально. p>
В
будь-якому випадку, на нашій системі репозиторій знаходиться в `/ usr/src/master '. У
цьому випадку ви повинні написати команди p>
`
setenv CVSROOT/usr/src/master ' p>
якщо
ваш командний інтерпретатор - csh або породжений від нього, або p>
`CVSROOT =/usr/src/master export
CVSROOT p>
якщо
це Bash або який-либой інший варіант Bourne shell. p>
Якщо
ви забудете зробити це, CVS поскаржиться, якщо ви спробуєте запустити його: p>
$ cvs checkout httpc p>
cvs checkout: No CVSROOT specified!
Please use the `-d 'option p>
cvs [checkout aborted]: or set the
CVSROOT environment variable. P>
$ p>
Витяг робочого каталогу h2>
CVS
не може працювати в звичайному дереві каталогів; навпаки, ви повинні працювати в
каталозі, який CVS створить для вас. Точно так само, як ви передплачуєте книгу
з бібліотеки перед тим, як забрати її з собою, вам слід використовувати
команду `cvs checkout ', щоб отримати від CVS робоче дерево каталогів.
Припустимо, наприклад, що ви працюєте над проектом, що називається `httpc ',
тривіальним HTTP клієнтом: p>
$ cd p>
$ cvs checkout httpc p>
U httpc/.cvsignore p>
U httpc/Makefile p>
U httpc/httpc.c p>
U
httpc/poll-server p>
$ p>
Команда
`cvs checkout httpc 'означає" Витягти дерево вихідних текстів з ім'ям
`httpc 'з репозиторію, зазначеного у змінній оточення` CVSROOT'. " p>
CVS
поміщає дерево в підкаталог `httpc ': p>
$ cd httpc p>
$ ls-l p>
total 8 p>
drwxr-xr-x 2 jimb 512 Oct 31 11:04
CVS p>
-rw-r - r - 1 jimb 89 Oct 31 10:42
Makefile p>
-rw-r - r - 1 jimb 4432 Oct 31 10:45
httpc.c p>
-rwxr-xr-x 1 jimb 460 Oct 30 10:21
poll-server p>
Більшість
цих файлів - робочі копії початкових текстів `httpc '. Однак, підкаталог з
ім'ям `CVS '(самий перший) має інше призначення. CVS використовує його для
зберігання додаткової інформації про кожен файл у цьому каталозі, щоб визначати,
які зміни ви внесли в них з тих пір, як витягували їх із репозиторію. p>
Редагування файлів h2>
Після
того, як CVS створив робочу дерево каталогів, ви можете звичайним чином
редагувати, компілювати і перевіряти що знаходяться в ньому файли - це просто
файли. p>
Наприклад,
припустимо, що ми хочемо скомпілювати проект, який ми тільки що
витягли: p>
$ make p>
gcc-g-Wall-lnsl-lsocket httpc.c
-o httpc p>
httpc.c: In function
`tcp_connection ': p>
httpc.c: 48: warning: passing arg 2
of `connect 'from incompatible p>
pointer
type p>
$ p>
Здається,
`httpc.c 'ще не був перенесений на цю операційну систему. Нам потрібно зробити
приведення типів для одного з аргументів функції connect. Щоб зробити це,
треба змінити рядок 48, замінивши p>
if
(connect (sock, & name, sizeof (name))> = 0) p>
на p>
if (connect (sock, (struct sockaddr
*) & Name, sizeof (name))> = 0) p>
$ make gcc-g-Wall-lnsl-lsocket p>
httpc.c-o httpc $ httpc GET
http://www.cyclic.com p>
... тут
знаходиться текст HTML з домашньої сторінки Cyclic Software ... p>
$
p>
Об'єднання змін h2>
Так
як кожен розробник використовує свій власний робочий каталог, зміни, які ви робите у своєму
каталоги, не стають автоматично
видимими Решта дівчат у вашій команді. CVS не публікує змін, поки вони не закінчені. Коли ви
протестуєте зміни, ви повинні "зафіксувати"
(commit) їх у репозиторії і зробити їх доступними іншим. Ми опишемо команду cvs commit далі. p>
Однак,
що якщо інший розробник змінив той же файл, що і ви, і, можливо, навіть змінив ті ж самі
рядка? Чиї зміни буде використано?
Зазвичай відповісти на це питання автоматично неможливо, і CVS абсолютно точно некомпетентний, щоб
приймати такі рішення. Тому перед
тим, як фіксувати ваші зміни, CVS вимагає, щоб вихідні тексти були синхронізовані з
всіма змінами, які зробили
решта членів групи. Команда cvs update подбає про це: p>
$ cvs update p>
cvs update: Updating. p>
U Makefile p>
RCS file:
/ u/src/master/httpc/httpc.c, v p>
retrieving revision 1.6 p>
retrieving revision 1.7 p>
Merging differences between 1.6 and
1.7 into httpc.c p>
M
httpc.c p>
$ p>
Розглянемо
приклад рядок за рядком: p>
`U
Makefile ' p>
Рядок
виду `U файл 'означає, що файл просто був оновлений; p>
хтось
ще вніс у цей файл зміни, і CVS скопіював змінений файл у ваш робочий каталог. p>
`RCS file :... p>
retrieving revision 1.6 p>
retrieving revision 1.7 p>
Merging differences between 1.6 and
1.7 into httpc.c ' p>
Це
повідомлення означає, що хтось ще змінив `httpc.c '; CVS об'єднала їх зміни з вашими і не виявила
текстуальні конфліктів. Цифри `1.6 'і
`1.7 '- це номери редакції (revision numbers), що використовуються для позначення певних точок історії файлу.
Зауважте, що CVS об'єднує зміни
тільки у вашій робочої копії; репозиторій і робочі каталоги інших розробників залишаються недоторканими. Від вас
потрібно протестувати об'єднаний текст
і переконатися, що він вірний. p>
`M
httpc.c ' p>
Рядок
виду `M файл 'означає, що файл був модифікований вами та містить зміни, які ще не стали
видно іншим розробникам. Це - зміни,
які вам слід зафіксувати. p>
Так
як CVS об'єднала чиїсь ще зміни з вашими вихідними текстами, слід переконатися, що вони все ще працюють: p>
$ make p>
gcc-g-Wall-lnsl-lsocket httpc.c
-o httpc p>
$ httpc GET http://www.cyclic.com p>
... HTML text for Cyclic Software's
home page follows ... p>
$ p>
Фіксування
змін p>
Тепер,
коли ви синхронізували свої вихідні коди з колегами і протестували їх, ви готові помістити свої
зміни до головного сховища і зробити їх видимими
іншим розробникам. Єдиний файл, який ви змінили - це `httpc.c ', але в будь-якому випадку можна без побоювання
запустити cvs update, щоб отримати від
CVS список модифікованих файлів: p>
$ cvs update p>
cvs update: Updating. p>
M
httpc.c p>
$ p>
Як
і очікувалося, єдиний файл, який згадує CVS - це `httpc.c '; CVS каже, що цей файл
містить зміни, які ще не були
зафіксовані. Ви можете зафіксувати їх так: p>
$ cvs
commit httpc.c p>
В
цьому місці CVS запустить ваш улюблений текстовий редактори попросить вас ввести опис змін. Після
того, як ви вийдете з редактора, CVS
зафіксує ваші зміни: p>
Checking
in httpc.c; p>
/u/src/master/httpc/httpc.c, v
<- httpc.c p>
new
revision: 1.8; previous revision: 1.7 p>
$ p>
Зауважте,
що тепер ви зафіксували ваші зміни та їх видно всім іншим членам групи. Коли
інший розробник виконує cvs update,
CVS внесе ваші зміни у файли в його робочому каталозі. p>
Відстеження змін h2>
Тепер
ви, можливо, захочете дізнатися, які саме зміни вніс інший розробник у файл `httpc.c '.
Щоб побачити журнальні записи для даного
файлу, можна використовувати команду cvs log: p>
$ cvs log httpc.c p>
RCS file:
/ usr/src/master/httpc/httpc.c, v p>
Working file: httpc.c p>
head: 1.8 p>
branch: p>
locks: strict p>
access list: p>
symbolic names: p>
keyword substitution: kv p>
total revisions: 8; selected
revisions: 8 p>
description: p>
The one and only source file for
trivial HTTP client p>
---------------------------- p>
revision 1.8 p>
date: 1996/10/31 20:11:14; author:
jimb; state: Exp; lines: +1 -1 p>
(tcp_connection): Cast address
stucture when calling connect. p>
---------------------------- p>
revision 1.7 p>
date: 1996/10/31 19:18:45; author:
fred; state: Exp; lines: +6 -2 p>
(match_header): Make this test
case-insensitive. p>
---------------------------- p>
revision 1.6 p>
date: 1996/10/31 19:15:23; author:
jimb; state: Exp; lines: +2 -6 p>
... p>
$ p>
Велику
частина тексту тут ви можете ігнорувати; варто лише звернути увагу на серію журнальних
записів після першого рядка рисок.
Журнальні записи виводяться на екран у зворотному хронологічному порядку, виходячи з припущення, що недавні
зміни звичайно більш цікаві. Кожна
запис описує одна зміна у файлі, і може бути розібрано на складові частини так: p>
`revision
1.8 ' p>
Кожна
версія файлу має унікальний "номер редакції". Номери ревізії виглядають як `1.1 ',` 1.2', `1.3.2.2 'або навіть
`1.3.2.2.4.5 '. За замовчуванням номер p>
1.1
- Це перша редакція файлу. Кожне наступне редагування збільшує p>
останню
цифру на одиницю. p>
`date:
1996/10/31 20:11:14; author: jimb; ...' p>
В
цьому рядку знаходиться дата зміни та ім'я користувача, що зафіксував p>
це
зміна; залишок рядки не дуже цікавий. p>
`(tcp_connection:
Cast ...' p>
Це,
очевидно, опис змін. p>
Команда
cvs log може вибирати журнальні записи за датою або за номером редакції; за описом деталей звертайтеся до
керівництву. p>
Якщо
ви хочете поглянути на відповідну зміну, то можете використовувати команду cvs diff.
Наприклад, якщо ви хочете побачити, які зміни
Фред зафіксував як редакції 1.7, використовуйте таку команду: p>
$ cvs diff-c-r 1.6-r 1.7 httpc.c p>
Перед
розглядом того, що нам видала ця команда, опишемо, що означає кожна її частина. p>
-c p>
Визначає використання зрозумілому людині форматі видачі
змін. (Цікаво, чому це не так за замовчуванням).
(1) p>
-r 1.6-r 1.7 p>
Вказує CVS, що необхідно видати зміни,
необхідні, щоб перетворити редакцію 1.6 в редакції 1.7. Ви можете
запросити більш широкий діапазон змін; наприклад,-r 1.6-r 1.8 відобразить
зміна, зроблені Фредом, і зміни, зроблені вами трохи пізніше. (Ви
також можете замовити видачу змін у зворотному порядку - як ніби-то вони
були скасовані - вказавши номери редакцій у зворотному порядку:-r 1.7-r 1.6.
Це звучить дивно, але іноді корисно.) P>
httpc.c p>
Файл для обробки. Якщо ви не вкажете його, CVS
видасть звіт про все каталозі. p>
Ось
що видасть ця команда: p>
Index: httpc.c p>
=============================================== ================== p>
RCS file:
/ u/src/master/httpc/httcp.c, v p>
retrieving revision 1.6 p>
retrieving revision 1.7 p>
diff-c-r1.6-r1.7 p>
*** httpc.c 1996/10/31 19:15:23 1.6 p>
--- httpc.c 1996/10/31 19:18:45 1.7 p>
*************** p>
*** 62,68 **** p>
) p>
!/* Return non-zero iff HEADER is a
prefix of TEXT. HEADER should be p>
null-terminated; LEN is the length
of TEXT. */ p>
static int p>
match_header (char * header, char
* text, size_t len) p>
--- 62,69 ---- p>
) p>
!/* Return non-zero iff HEADER is a
prefix of TEXT, ignoring p>
! differences in case. HEADER should
be lower-case, and p>
null-terminated; LEN is the length
of TEXT. */ p>
static int p>
match_header (char * header, char
* text, size_t len) p>
*************** p>
*** 76,81 **** p>
--- 77,84 ---- p>
for (i = 0; i
( p>
char t = text [i]; p>
+ if ( 'A' <= t & & t <=
'Z') p>
+ t + = 'a' - 'A'; p>
if (header [i]! = t) p>
return
0; p>
) p>
$ p>
Потрібні
деякі зусилля, щоб звикнути до такої подачі інформації, але це безперечно варто того.
(2) p>
Цікава
частина інформації починається з перших двох рядків, що починаються з *** и ---; вони описують старий
і новий файли, що підлягають порівнянню.
Останнє складається з двох "скибок" (hunk), кожен з яких починається з рядка з зірочок. Ось перший "шмат": p>
*************** p>
*** 62,68 **** p>
) p>
!/* Return non-zero iff HEADER is a
prefix of TEXT. HEADER should be p>
null-terminated; LEN is the length
of TEXT. */ p>
static int p>
match_header (char * header, char
* text, size_t len) p>
--- 62,69 ---- p>
) p>
!/* Return non-zero iff HEADER is a
prefix of TEXT, ignoring p>
! differences in case. HEADER should
be lower-case, and p>
null-terminated; LEN is the length
of TEXT. */ p>
static int p>
match_header (char * header, char
* text, size_t len) p>
Текст
з більш старої редакції знаходиться після рядка *** 62,68 p>
***;
текст нової редакції знаходиться після рядка --- 62,69 ---. Пара цифр p>
означає
показаний проміжок рядків. CVS показує контекст навколо змін і p>
відзначає
змінені рядки символами `! '. Таким чином ви бачите, що один p>
рядок
з верхньої половини була замінена на два рядки з нижньої. p>
Ось друга "шмат": p>
*************** p>
*** 76,81 **** p>
--- 77,84 ---- p>
for (i = 0; i
( p>
char t = text [i]; p>
+ if ( 'A' <= t & & t <=
'Z') p>
+ t + = 'a' - 'A'; p>
if (header [i]! = t) p>
return
0; p>
) p>
Тут
описується додавання двох рядків, що позначається символами `+ '. CVS не виводить старий текст --
це було б надто. Для опису
видалених рядків використовується подібний формат. Як і вихід команди diff, вихід команди cvs
diff зазвичай називається
"латкою" (patch), тому що розробники традиційно використовували цей формат для розповсюдження виправлень і
невеликих новий можливостей. Досить
читабельним, латка містить достатньо інформації, щоб застосувати зміни, які вона містить, до текстового
файлу. Насправді, команда patch
в середовищі UNIX робить з латками саме це. p>
Додавання та видалення файлів h2>
CVS
звертається з додаванням і видаленням файлів так само, як і з іншими змінами, записуючи такі події в
історії файлів. Можна дивитися на це
так, як ніби CVS зберігає історію каталогів разом з історією файлів. CVS не вважає, що створені файли повинні
опинитися під його контролем; це не так
в багатьох випадках. Наприклад, не потрібно записувати історію змін об'єктних і виконуваних
файлів, тому що їх вміст завжди
може бути відтворено з вихідних файлів (треба сподіватися). Замість цього, коли ви створите новий файл, cvs update
маркує це фото прапором `? ', поки ви
не скажете CVS, що саме ви маєте намір зробити з цим файлом. p>
Щоб
додати файл до проекту, спочатку ви повинні створити його, а потім за допомогою команди cvs add, щоб
маркувати його як доданий. Потім за
наступному виконанні команди cvs commit CVS додасть це фото в репозиторій. p>
Наприклад,
ось так можна додати файл README в проект httpc: p>
$ ls p>
CVS Makefile httpc.c poll-server p>
$
vi README p>
... введіть
опис httpc ... p>
$ ls p>
CVS Makefile README httpc.c
poll-server p>
$ cvs update p>
cvs update: Updating. p>
?
README --- CVS ще не знає про цей файл p>
$ cvs add README p>
cvs add: scheduling file `README '
for addition p>
cvs add: use 'cvs commit' to add
this file permanently p>
$
cvs update --- що ж тепер думає CVS? p>
cvs
update: Updating. p>
A
README --- Файл позначений як доданий p>
$
cvs commit README p>
...
CVS просить вас ввести журнальну запис ... p>
RCS file:
/ u/jimb/cvs-class/rep/httpc/README, v p>
done p>
Checking in README; p>
/u/src/master/httpc/README, v <--
README p>
initial
revision: 1.1 p>
done p>
$ p>
CVS
звертається з віддаленими файлами майже так само. Якщо ви видалите файл і виконайте `cvs update ', CVS НЕ
вважає, що ви маєте намір видалити
файл з проекту. Замість цього він вступає милосерднішими - він відновлює останню збережену в
репозиторії версію файлу та маркує його прапором U, точно так само, як і будь-який інший
оновлення. (Це означає, що якщо ви
хочете скасувати зміни файлу у робочому каталозі, ви можете просто видалити його і дозволити команді `cvs update 'створити
його заново.) p>
Щоб
видалити файл з проекту, ви повинні спочатку видалити його, а потім використовувати команду `cvs rm ', щоб
позначити його для видалення. При наступному
запуску команда `cvs commit 'видалить файл з репозиторію. Фіксування файлу, маркованого за допомогою
`cvs rm 'не знищує історію цього
файлу - до неї просто додається ще одна редакція --- "не існує". У репозиторії по
як і раніше, зберігаються всі записи про цей файл, і до них можна звертатися за бажанням - наприклад,
за допомогою `cvs diff '
або `cvs log '. p>
Для
перейменування файлу існує кілька стратегій; найпростіша --- перейменувати файл у робочому каталозі,
потім виконати `cvs rm 'зі старим
ім'ям і `cvs add 'з новим. Недолік цього підходу в тому, що журнальні записи про вміст старого файлу
не переносяться в новий файл. Інші стратегії
дозволяють уникнути цього, але зате доставляють інші, більш дивні проблеми. p>
Ви
можете додавати каталоги точно також, як і звичайні файли. p>
Написання
хороших журнальних записів Якщо можна використовувати `cvs diff ', щоб отримати
точний зміст будь-якої зміни, то навіщо тоді вигадувати ще журнальну
запис про нього? Очевидно, що журнальні записи коротше, ніж тексти змін, і
дозволяють читачеві отримати загальне розуміння зміни без необхідності
заглиблюватися в деталі. p>
Однак
ж, хороша запис в журналі описує причину, з якої було зроблено
зміна. Наприклад, погана журнальний запис для редакції 1.7 може звучати
як "Перетворити` t 'до нижнього регістру ". Це правильно, але
марно - `cvs diff 'надає точно ту ж інформацію, і набагато ясніше.
Набагато кращою журнальної записом було б "Зробити цю перевірку
незалежний від регістру ", тому що це набагато ясніше описує причину
будь-кому, хто розуміє, що відбувається в коді - клієнти HTTP повинні ігнорувати
регістр букв при аналізі заголовків відповіді від сервера. p>
Обробка
конфліктів Як уже згадувалося, команда `cvs update 'об'єднує іЗміна,
зроблені іншими розробниками, з вихідними текстами у вашому робочому
каталозі. Якщо ви відредагували файл одночасно з кимось іншим, CVS
об'єднає ваші зміни. p>
Досить
легко уявити собі, як працює об'єднання, якщо зміни були здійснені
в різних ділянках файлу, але що якщо ви обидва змінили одну й ту ж рядок? CVS
називає цю ситуацію конфлікт і надає вам самому розібратися з ним. p>
Наприклад,
припустимо, що ви додали певну перевірку на помилки у код, що визначає адресу
сервера. Перед фіксуванням змін ви повинні запустити `cvs update ', щоб
синхронізувати ваш робочий каталог з репозиторієм: p>
$
cvs update p>
cvs
update: Updating. p>
RCS file:
/ u/src/master/httpc/httpc.c, v p>
retrieving revision 1.8 p>
retrieving revision 1.9 p>
Merging differences between 1.8 and
1.9 into httpc.c p>
rcsmerge: warning: conflicts during
merge p>
cvs update: conflicts found in
httpc.c p>
C
httpc.c p>
$ p>
В
цьому випадку інший розробник змінив ту саму ділянку файлу, що і ви, тому CVS скаржиться на конфлікт.
Замість того, щоб надрукувати M httpc.c,
як це зазвичай відбувається, CVS друкує C httpc.c, що означає наявність конфлікту в цьому файлі. p>
Щоб
впоратися з конфліктом, відкрийте цей файл у редакторі. CVS позначає конфліктує текст так: p>
/* Look up the IP address of the
host. */ p>
host_info = gethostbyname
(hostname); p>
<<<<<<< httpc.c p>
if (! host_info) p>
( p>
fprintf (stderr, "% s: host not
found:% sn ", progname, hostname); p>
exit (1); p>
) p>
======= p>
if (! host_info) p>
( p>
printf ( "httpc: no host "); p>
exit (1); p>
) p>
>>>>>>> 1.9 p>
sock = socket (PF_INET, SOCK_STREAM,
0); p>
Текст
вашого робочого файлу з'являється зверху, після символів <<<. Внизу знаходиться конфліктує
код іншого розробника. Номер редакції
1.9 вказує, що конфліктуючі зміна була внесена в Версія 1.9 цього файлу, спрощуючи перевірку журнальних
записів або просто з'ясування змін з
допомогою `cvs diff '. p>
Коли
ви вирішите, як саме впоратися з конфліктом, приберіть маркери з коду і відредагуйте його. У цьому
разі, так як ваша обробка помилок
безперечно краще, то просто відкиньте чужий варіант, залишивши такий код:/* Look up the IP address of the host. */Host_info = gethostbyname (hostname); if (!
host_info) p>
( p>
fprintf (stderr, "% s: host not
found:% sn ", progname, hostname); p>
exit (1); p>
) p>
sock = socket (PF_INET, SOCK_STREAM,
0); p>
Тепер
протестуйте зміни і зафіксуйте їх: p>
$ make p>
gcc-g-Wall-Wmissing-prototypes
-lnsl-lsocket httpc.c-o httpc p>
$ httpc GET http://www.cyclic.com p>
HTTP/1.0 200 Document follows p>
Date: Thu, 31 Oct 1996 23:04:06 GMT p>
... p>
$ httpc GET http://www.frobnitz.com p>
httpc: host not found:
www.frobnitz.com p>
$
cvs commit httpc.c p>
Важливо
розуміти, що саме CVS вважає конфліктом. CVS не розуміє семантики вашої програми, він
звертається з вихідним кодом просто як з деревом текстових файлів. Якщо один
розробник додає новий аргумент на функцію
і виправляє всі її виклики, поки інший розробник одночасно додає новий виклик цієї функції, і не
передає їй цей новий аргумент, що виразно
є конфліктом - дві зміни несумісні - але CVS не повідомить про це. Його розуміння конфліктів
строго текстуально. На практиці, однак,
конфлікти трапляються рідко. Зазвичай вони відбуваються
тому, що дві людини намагаються впоратися з однією і тією ж проблемою, від нестачі взаємодії між
розробниками, або від розбіжностей по
приводу архітектури програми. Правильною розподіл завдань між розробниками зменшує ймовірність
конфліктів. Багато систем контролю
версій дозволяють розробнику блокувати
файл, запобігаючи внесення до нього змін до тих пір, поки його власні зміни не будуть зафіксовані.
Незважаючи на те, що блокування доречні в
деяких ситуаціях, це не завжди підхід краще, ніж підхід CVS. Зміни зазвичай об'єднуються без проблем, а
розробники іноді забувають її розблокувати,
в обох випадках явне блокування призводить до непотрібних затримок. Більш того, блокування запобігають тільки
текстуальні конфлікти - вони нічого не
можуть вдіяти із семантичними конфліктами типу вищеописаного - коли два розробники редагують різні файли. p>
Footnotes
p>
(1)
Цікаво, чому це взагалі не-u? Прим. перекл.
p>
(2)
Все-таки краще використати-u. Прим. перекл. p>
Список
літератури p>
Для
підготовки даної роботи були використані матеріали з сайту
http://www.citforum.ru/ p>
Як
змусити гру працювати швидше p>
Автор:
Antiloop, Куточок DirectX. p>
В
цій маленькій статті я дам кілька зібраних мною порад як зробити ваш
програмний код для DirectX більш швидким. p>
По-перше,
якщо ви хочете працювати з DirectX, переходите на VB6. Сама програма шостого
Бейсіка працює швидше, ніж програма п'ятий (спасибі компілятору).
По-друге, бібліотека сьомого DirectX від Microsoft працює набагато (!)
швидше, ніж Patrice Scribe TLB (неповна функціональність це вже окремий
розмова). p>
Отже,
про компілятор начебто сказав. Вам не буде потрібно компілювати всю програму,
якщо ви хочете подивитися тільки маленьке зміна, тому що робить це Сі.
Проте сама програма Visual Basic працює у багато разів повільніше програми на
Сі - і знову це заслуга компілятора, ну не може він відучити прогу від рідної
msvbvm60 бібліотеки. : ( P>
Ось
деякі поради, які допоможуть вам зробити вашу DirectX гру більш швидкою: p>
Якщо
ви робите бліттінг в DirectX за допомогою програмного драйвера, а не
апаратного прискорення, то використовуйте функцію BltFast, якщо вам треба просто
перенести спрайт, а не використовувати розтягування, обертання і т. п. BltFast
працює приблизно на 10% швидше, ніж функція Blt, а також просто зручніше в
використанні, тому що вам треба передавати менше структур. p>
DirectDraw
і Direct3D набагато швидше на весь екран, ніж у віконному p>
Уникайте
дуже багато операцій бліттінга. p>
Уникайте
створення великої кількості поверхонь. Не створюйте масиви поверхонь.
Прагніть розміщувати якомога більше спрайтів на одній поверхні. p>
Якщо
ви робите гру з великою кількістю спрайтів та/або тайлів, спробуйте
розміщувати їх в масиви структур, створювати класи або що-небудь в цьому роді.
Таким чином, коли вам треба буде вивести всі спрайт, ви можете намалювати
їх в один цикл типу цього: p>
Dim i As Long p>
For i = 0 To NUM_SPRITES p>
Call Sprite (i). DoAI p>
Call Sprite (i). Move p>
Call Sprite (i). Draw p>
Next i p>
В
тайлових іграх намагайтеся не промальовувати всю карту (я маю на увазі видиму
частина) щоразу, коли спрайт героя рухається. Постарайтеся зробити
процедуру, яка буде промальовувати за один раз одну колонку або рядок. p>
Уникайте
великої кількості циклів. Намагайтеся зробити якомога більше роботи за один
цикл. p>
Спробуйте
зробити декілька "процесів". Операції бліттінга і фліппінга, а
також очікування нового циклу оновлення екрану займають час і в цей час
комп'ютер нічого не робить. Постарайтеся зробити паралельний процес, який
буде в цей час обраховувати, ну скажімо наступну позицію спрайту. p>
Якщо
Ви створюєте Direct3D гру, виконайте пошук пристрою, найбільш відповідного для
D3D p>
Ramp
емуляція завжди краще RGB емуляції, проте жодна з них не зрівняється з HAL
(Hardware Acceleration Layer - рендеринг через апаратне прискорення). p>
В
Direct3D Retained Mode при рендеринга великої кількості багатокутників без
використання HAL використовуйте Flat shading. Цей ефект набагато швидше Gouraud
shading. p>
Без
апаратного прискорення позбавляйтеся ефекту Dithering (згладжування пікселів).
Звичайно гра бидет виглядати з ним краще, але це дуже сильно гальмує
програму. Якщо використовуєте HAL, тоді поверніть Dithering на місце:) p>
Не
треба весь час ініціалізувати об'єкти, як тільки вони вам знадобляться.
Ініціалізувати об'єкт один раз - набагато краще, ніж робити це двічі і
тричі. По-перше, вам не треба другий раз турбується про помилки, які можуть
бути при ініціалізації, а по-друге знаєте як дратує, коли гра при
виході з меню починає жувати вінчестером ???!!!! p>
Уникайте
безлічі змінних Public і довгих масивів. Вони жеруть більше стекового місця
протягом всього сеансу запуску програми і вони можуть загальмувати програму.
p>
Намагайтеся
не робити чогось якщо можна цього не робити. VB ще не настільки швидкий, щоб
дозволяти собі багато ефектів. Намагайтеся робити програму менше, а код
швидше. p>
Список літератури h2>
Для
підготовки даної роботи були використані матеріали з сайту http://www.citforum.ru/
p>