AVR Таймеры. Ссылки.
docviewer.yandex.ru/view/197762593/?*=AjoOQLJvYqSpQCqDGlFkX8nd%2BF57InVybCI6InlhLWRpc2stcHVibGljOi8vM1N2dTRRbTNPdGVESEJGK0wyak9rVG1rOS9MYUl3TGpqN3poUXJvTzUyQT0iLCJ0aXRsZSI6IkFUbWVnYThfcnVzLnBkZiIsInVpZCI6IjE5Nzc2MjU5MyIsInl1IjoiNjAxMDY5MjE5MTQ5OTM3MzUxOCIsIm5vaWZyYW1lIjpmYWxzZSwidHMiOjE1MDA1NTMxMDIyNDR9
atmega8.ru/wiki/view/doc.22.html
mkprog.ru/avr/avr-dlya-nachinayushhih-urok-5-tajmery.html
///////////////////////////////////////////////////////////////////////////////////////////
mainloop.ru/avr-atmega/avr-timer-counter.html
easyelectronics.ru/avr-uchebnyj-kurs-tajmery.html
chipenable.ru/index.php/programming-avr/item/171-avr-timer-t0-ch1.html
chipenable.ru/index.php/programming-avr/item/187-uchebnyy-kurs-avr-taymer-schetchik-t0-rezhim-normal-ch2.html
avr-start.ru/?p=414
narodstream.ru/avr-urok-10-tajmery-schetchiki-preryvaniya/
samou4ka.net/page/tajmer-schetchik-mikrokontrollerov-avr
atmega8.ru/wiki/view/doc.22.html
mkprog.ru/avr/avr-dlya-nachinayushhih-urok-5-tajmery.html
///////////////////////////////////////////////////////////////////////////////////////////
mainloop.ru/avr-atmega/avr-timer-counter.html
easyelectronics.ru/avr-uchebnyj-kurs-tajmery.html
chipenable.ru/index.php/programming-avr/item/171-avr-timer-t0-ch1.html
chipenable.ru/index.php/programming-avr/item/187-uchebnyy-kurs-avr-taymer-schetchik-t0-rezhim-normal-ch2.html
avr-start.ru/?p=414
narodstream.ru/avr-urok-10-tajmery-schetchiki-preryvaniya/
samou4ka.net/page/tajmer-schetchik-mikrokontrollerov-avr
Android Moxy
www.youtube.com/watch?v=eZyoJkmxGHE
www.youtube.com/watch?v=KoYX-6CYi3Q
www.youtube.com/watch?v=KZ0j2K9VAf8
www.youtube.com/watch?v=KZ0j2K9VAf8
www.slideshare.net/YuriShmakov/moxy
github.com/Arello-Mobile/Moxy/blob/master/sample-github/src/main/java/com/arellomobile/mvp/sample/github/mvp/views/HomeView.java
github.com/Arello-Mobile/Moxy/blob/master/sample-github/src/main/java/com/arellomobile/mvp/sample/github/ui/activities/HomeActivity.java
habrahabr.ru/company/redmadrobot/blog/274897/
habrahabr.ru/company/redmadrobot/blog/305798/
www.youtube.com/watch?v=KoYX-6CYi3Q
github.com/Arello-Mobile/Moxy
habrahabr.ru/post/276189/
habrahabr.ru/post/275255/
www.youtube.com/watch?v=KoYX-6CYi3Q
www.youtube.com/watch?v=KZ0j2K9VAf8
www.youtube.com/watch?v=KZ0j2K9VAf8
www.slideshare.net/YuriShmakov/moxy
github.com/Arello-Mobile/Moxy/blob/master/sample-github/src/main/java/com/arellomobile/mvp/sample/github/mvp/views/HomeView.java
github.com/Arello-Mobile/Moxy/blob/master/sample-github/src/main/java/com/arellomobile/mvp/sample/github/ui/activities/HomeActivity.java
habrahabr.ru/company/redmadrobot/blog/274897/
habrahabr.ru/company/redmadrobot/blog/305798/
www.youtube.com/watch?v=KoYX-6CYi3Q
github.com/Arello-Mobile/Moxy
habrahabr.ru/post/276189/
habrahabr.ru/post/275255/
Примеры кода
habrahabr.ru/post/249015/
habrahabr.ru/post/259303/
through-the-interface.typepad.com/through_the_interface/2006/09/working_with_sp.html
arxdummies.blogspot.ru/2005/02/class-2-autocads-database.html
sites.google.com/site/bushmansnetlaboratory/translate-manual/sozdanie-i-redaktirovanie-obektov-autocad/rabota-s-vybrannymi-naborami
Доступ к базе данных открытого документа и итерирование по пространству модели с выводом в консоль типов всех объектов
ИТЕРИРОВАНИЕ ПО ВСЕМ СЛОЯМ С ПОЛУЧЕНИЕМ ОБЪЕКТОВ КАЖДОГО СЛОЯ
through-the-interface.typepad.com/through_the_interface/2008/05/finding-all-the.html
habrahabr.ru/post/259303/
through-the-interface.typepad.com/through_the_interface/2006/09/working_with_sp.html
arxdummies.blogspot.ru/2005/02/class-2-autocads-database.html
sites.google.com/site/bushmansnetlaboratory/translate-manual/sozdanie-i-redaktirovanie-obektov-autocad/rabota-s-vybrannymi-naborami
Доступ к базе данных открытого документа и итерирование по пространству модели с выводом в консоль типов всех объектов
//// Open the model space block table record.
////
AcDbBlockTable *pBlkTbl;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForRead);
AcDbBlockTableRecord *pBlkTblRcd;
pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd,
AcDb::kForRead);
pBlkTbl->close();
AcDbBlockTableRecordIterator *pBlkTblRcdItr;
pBlkTblRcd->newIterator(pBlkTblRcdItr);
AcDbEntity *pEnt;
for (pBlkTblRcdItr->start(); !pBlkTblRcdItr->done(); pBlkTblRcdItr->step())
{
pBlkTblRcdItr->getEntity(pEnt,
AcDb::kForRead);
acutPrintf(L"\n-- %s",
(pEnt->isA())->name());
pEnt->close();
}
pBlkTblRcd->close();
delete pBlkTblRcdItr;
acedRetVoid();
public void CreateSolidsAndCheckIntersect() // This method can have any name
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
bool intersect = false;
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
// Create the solid and set the history flag
Solid3d sol = new Solid3d();
// ранее здесь находился код создания цилиндра
sol1.CreateBox(100.0, 500.0, 35.0);
// Add the Solid3d to the modelspace
BlockTable bt = (BlockTable)tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
);
BlockTableRecord ms = (BlockTableRecord)tr.GetObject(
bt[BlockTableRecord.ModelSpace],
OpenMode.ForWrite
);
ms.AppendEntity(sol1);
tr.AddNewlyCreatedDBObject(sol1, true);
// And transform it to the selected point
// основной метод для перемещения объектов
sol1.TransformBy(
Matrix3d.Displacement(pt - Point3d.Origin)
);
Point3dCollection pts = new Point3dCollection();
Plane one = new Plane(Point3d.Origin, new Vector3d(5d,0d,0d), new Vector3d(0d, 0d, 5d));
//ent.BoundingBoxIntersectWith(ent1, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero);
Point3d thePoint = Point3d.Origin;
Autodesk.AutoCAD.BoundaryRepresentation.Brep brepEnt = new Brep(sol1);
PointContainment pointCont;
brepEnt.GetPointContainment(thePoint, out pointCont);
if (pointCont == PointContainment.Inside)
{
intersect = true;
}
foreach (ObjectId id in ms)
{
DBObject obj = (DBObject) tr.GetObject(id, OpenMode.ForRead);
Entity ent = (Entity)obj;
ed.WriteMessage("\nType:" + ent.GetType().ToString());
}
Point3d p3dMax = sol1.GeometricExtents.MaxPoint; //получаем самую верхнюю точку bounding box
Point3d p3dMin = sol1.GeometricExtents.MinPoint; //получаем самую нижнюю точку bounding box
Brep brep1 = new Brep(sol1); //получаем B-Rep - представление объекта
BrepVertexCollection vert_coll = brep1.Vertices; //Получаем массив вершин
List<Autodesk.AutoCAD.BoundaryRepresentation.Vertex> vert_list = new List<Autodesk.AutoCAD.BoundaryRepresentation.Vertex>();
foreach (Autodesk.AutoCAD.BoundaryRepresentation.Vertex vert in vert_coll)
{
vert_list.Add(vert);
}
Document document = Application.DocumentManager.MdiActiveDocument;
Editor editor;
if (document != null)
{
editor = document.Editor;
editor.WriteMessage("Min Point is" + p3dMin.ToString());
editor.WriteMessage("Intersect" + intersect.ToString());
}
tr.Commit();
}
}
ИТЕРИРОВАНИЕ ПО ВСЕМ СЛОЯМ С ПОЛУЧЕНИЕМ ОБЪЕКТОВ КАЖДОГО СЛОЯ
through-the-interface.typepad.com/through_the_interface/2008/05/finding-all-the.html
Список сайтов с документацией по ObjectARX
help.autodesk.com/view/OARX/2018/ENU/?guid=OREFNET-Autodesk_AutoCAD_DatabaseServices_Solid3d_CreateBox_double_double_double
help.autodesk.com/view/ACD/2016/ENU/?guid=GUID-9E9D7A74-4FE7-4E57-B9CB-BA4712B364ED
drive-cad-with-code.blogspot.ru/2011/01/creating-move-command-with-net-api-take.html
drive-cad-with-code.blogspot.ru/2009/
bushman-andrey.blogspot.ru/2012/10/autocad.html
bushman-andrey.blogspot.ru/2012/10/autocad.html
adn-cis.org/ispolzovanie-tranzitnoj-grafiki.html
www.caduser.ru/forum/index.php?PAGE_NAME=message&FID=24&TID=45423&MID=253560#message253560
forum.dwg.ru/search.php?searchid=11041462
knowledge.autodesk.com/search?search=solid&p=ACD&sort=score
help.autodesk.com/view/ACD/2016/ENU/?guid=GUID-9E9D7A74-4FE7-4E57-B9CB-BA4712B364ED
drive-cad-with-code.blogspot.ru/2011/01/creating-move-command-with-net-api-take.html
drive-cad-with-code.blogspot.ru/2009/
bushman-andrey.blogspot.ru/2012/10/autocad.html
bushman-andrey.blogspot.ru/2012/10/autocad.html
adn-cis.org/ispolzovanie-tranzitnoj-grafiki.html
www.caduser.ru/forum/index.php?PAGE_NAME=message&FID=24&TID=45423&MID=253560#message253560
forum.dwg.ru/search.php?searchid=11041462
knowledge.autodesk.com/search?search=solid&p=ACD&sort=score
Конспектирование книги "Скрапинг сайтов на Python"
Документация BeuatifulSoup — www.crummy.com/software/BeautifulSoup/bs4/doc/#find-all
Минимальный набор кода для работы с BS4:
Глава 1. Резюме.
Минимальный набор кода для работы с BS4:
from urllib.request import urlopen # импортируем функцию для получения html - кода
from bs4 import BeautifulSoup # импортируем BeautifulSoup
#открываем адрес и получаем html
html = urlopen("http://solovievspb.biznlife.ru/?utm_source=vktarget21-35&utm_medium=test_zagolovkov&utm_campaign=ob4")
# преобразуем Hmtl код в объект BeautifulSoup (с помощью этого объекта мы можем получать информацию)
bsObj = BeautifulSoup(html)
# с помощью объекта BeautifulSoup и функции findAll() получаем все тэги <p> в виде списка
Plist = bsObj.findAll("p")
# проходим по каждому члену списка, функция get_text() отделяет тэги от контента тэгов и возвращает этот контент
for p in Plist:
print(p.get_text())
Глава 1. Резюме.
Список библиотек Python
Парсинг
parsing.valemak.com/ru/python/library/
ru.stackoverflow.com/questions/37254/Какую-библиотеку-web-парсинга-для-python-выбрать
stackoverflow.com/questions/25539330/speeding-up-beautifulsoup
sasha.shestakoff.com/blog/2011/09/07/eshhe-odna-biblioteka-dlya-parsinga-saytov-na-python/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
Работа с данными
tproger.ru/digest/python-data-library/
techcave.ru/posts/39-biblioteki-python-dlja-analiza-dannyh.html
parsing.valemak.com/ru/python/library/
ru.stackoverflow.com/questions/37254/Какую-библиотеку-web-парсинга-для-python-выбрать
stackoverflow.com/questions/25539330/speeding-up-beautifulsoup
sasha.shestakoff.com/blog/2011/09/07/eshhe-odna-biblioteka-dlya-parsinga-saytov-na-python/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
Работа с данными
tproger.ru/digest/python-data-library/
techcave.ru/posts/39-biblioteki-python-dlja-analiza-dannyh.html
Preserving Object References
www.newtonsoft.com/json/help/html/PreserveObjectReferences.htm
By default Json.NET will serialize all objects it encounters by value. If a list contains two Person references and both references point to the same object, then the JsonSerializer will write out all the names and values for each reference.
In most cases this is the desired result, but in certain scenarios writing the second item in the list as a reference to the first is a better solution. If the above JSON was deserialized now, then the returned list would contain two completely separate Person objects with the same values. Writing references by value will also cause problems on objects where a circular reference occurs.
PreserveReferencesHandling
Setting PreserveReferencesHandling will track object references when serializing and deserializing JSON.
By default Json.NET will serialize all objects it encounters by value. If a list contains two Person references and both references point to the same object, then the JsonSerializer will write out all the names and values for each reference.
Person p = new Person
2{
3 BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc),
4 LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc),
5 Name = "James"
6};
7
8List<Person> people = new List<Person>();
9people.Add(p);
10people.Add(p);
11
12string json = JsonConvert.SerializeObject(people, Formatting.Indented);
13//[
14// {
15// "Name": "James",
16// "BirthDate": "1980-12-23T00:00:00Z",
17// "LastModified": "2009-02-20T12:59:21Z"
18// },
19// {
20// "Name": "James",
21// "BirthDate": "1980-12-23T00:00:00Z",
22// "LastModified": "2009-02-20T12:59:21Z"
23// }
24//]
In most cases this is the desired result, but in certain scenarios writing the second item in the list as a reference to the first is a better solution. If the above JSON was deserialized now, then the returned list would contain two completely separate Person objects with the same values. Writing references by value will also cause problems on objects where a circular reference occurs.
PreserveReferencesHandling
Setting PreserveReferencesHandling will track object references when serializing and deserializing JSON.
Создание плагинов для продуктов Autodesk. Начало.
Создание плагинов для продуктов Autodesk
Environment Variables
To run any Open CASCADE Technology application you need to set the environment variables.
On Windows
You can define the environment variables with env.bat script located in the $CASROOT folder. This script accepts two arguments to be used: the version of Visual Studio (vc8 – vc12) and the architecture (win32 or win64).
The additional environment settings necessary for compiling OCCT libraries and samples by Microsoft Visual Studio can be set using script custom.bat located in the same folder. You might need to edit this script to correct the paths to third-party libraries if they are installed on your system in a non-default location.
Script msvc.bat can be used with the same arguments for immediate launch of Visual Studio for (re)compiling OCCT.
On Unix
If OCCT was built by Code::Blocks, you can define the environment variables with env_cbp.sh or custom_cbp.sh script.
If OCCT was built by Automake, you can define the environment variables with env_amk.sh or custom_amk.sh script.
The scripts are located in the OCCT root folder.
Description of system variables:
CASROOT is used to define the root directory of Open CASCADE Technology;
PATH is required to define the path to OCCT binaries and 3rdparty folder;
LD_LIBRARY_PATH is required to define the path to OCCT libraries (on UNIX platforms only);
MMGT_OPT (optional) if set to 1, the memory manager performs optimizations as described below; if set to 2, Intel ® TBB optimized memory manager is used; if 0 (default), every memory block is allocated in C memory heap directly (via malloc() and free() functions). In the latter case, all other options starting with MMGT, except MMGT_CLEAR, are ignored;
MMGT_CLEAR (optional) if set to 1 (default), every allocated memory block is cleared by zeros; if set to 0, memory block is returned as it is;
MMGT_CELLSIZE (optional) defines the maximal size of blocks allocated in large pools of memory. Default is 200;
MMGT_NBPAGES (optional) defines the size of memory chunks allocated for small blocks in pages (operating-system dependent). Default is 10000;
MMGT_THRESHOLD (optional) defines the maximal size of blocks that are recycled internally instead of being returned to the heap. Default is 40000;
MMGT_MMAP (optional) when set to 1 (default), large memory blocks are allocated using memory mapping functions of the operating system; if set to 0, they will be allocated in the C heap by malloc();
CSF_LANGUAGE (optional) defines default language of messages;
CSF_DEBUG (optional, Windows only): if defined then a diagnostic message is displayed in case of an exception;
CSF_DEBUG_BOP (optional): if defined then it should specify directory where diagnostic data on problems occured in Boolean operations will be saved;
CSF_MDTVTexturesDirectory defines the directory for available textures when using texture mapping;
CSF_ShadersDirectory defines the directory for GLSL programs (required for 3D viewer to work);
CSF_UnitsDefinition and CSF_UnitsLexicon should define paths to resource files Lexi_Expr.dat and Units.dat, respectively (required for support of measurement units);
CSF_SHMessage defines the path to the messages file for ShapeHealing;
CSF_XSMessage defines the path to the messages file for STEP and IGES translators;
CSF_StandardDefaults, CSF_StandardLiteDefaults*, **CSF_XCAFDefaults, and CSF_PluginDefaults define paths to directory where configuration files for OCAF persistence are located (required for open/save operations with OCAF documents);
CSF_IGESDefaults and CSF_STEPDefaults (optional) define paths to directory where resource files of IGES and STEP translators are located;
CSF_XmlOcafResource is required in order to set the path to XSD resources, which defines XML grammar.
CSF_MIGRATION_TYPES is required in order to read documents that contain old data types, such as TDataStd_Shape;
On Windows
You can define the environment variables with env.bat script located in the $CASROOT folder. This script accepts two arguments to be used: the version of Visual Studio (vc8 – vc12) and the architecture (win32 or win64).
The additional environment settings necessary for compiling OCCT libraries and samples by Microsoft Visual Studio can be set using script custom.bat located in the same folder. You might need to edit this script to correct the paths to third-party libraries if they are installed on your system in a non-default location.
Script msvc.bat can be used with the same arguments for immediate launch of Visual Studio for (re)compiling OCCT.
On Unix
If OCCT was built by Code::Blocks, you can define the environment variables with env_cbp.sh or custom_cbp.sh script.
If OCCT was built by Automake, you can define the environment variables with env_amk.sh or custom_amk.sh script.
The scripts are located in the OCCT root folder.
Description of system variables:
CASROOT is used to define the root directory of Open CASCADE Technology;
PATH is required to define the path to OCCT binaries and 3rdparty folder;
LD_LIBRARY_PATH is required to define the path to OCCT libraries (on UNIX platforms only);
MMGT_OPT (optional) if set to 1, the memory manager performs optimizations as described below; if set to 2, Intel ® TBB optimized memory manager is used; if 0 (default), every memory block is allocated in C memory heap directly (via malloc() and free() functions). In the latter case, all other options starting with MMGT, except MMGT_CLEAR, are ignored;
MMGT_CLEAR (optional) if set to 1 (default), every allocated memory block is cleared by zeros; if set to 0, memory block is returned as it is;
MMGT_CELLSIZE (optional) defines the maximal size of blocks allocated in large pools of memory. Default is 200;
MMGT_NBPAGES (optional) defines the size of memory chunks allocated for small blocks in pages (operating-system dependent). Default is 10000;
MMGT_THRESHOLD (optional) defines the maximal size of blocks that are recycled internally instead of being returned to the heap. Default is 40000;
MMGT_MMAP (optional) when set to 1 (default), large memory blocks are allocated using memory mapping functions of the operating system; if set to 0, they will be allocated in the C heap by malloc();
CSF_LANGUAGE (optional) defines default language of messages;
CSF_DEBUG (optional, Windows only): if defined then a diagnostic message is displayed in case of an exception;
CSF_DEBUG_BOP (optional): if defined then it should specify directory where diagnostic data on problems occured in Boolean operations will be saved;
CSF_MDTVTexturesDirectory defines the directory for available textures when using texture mapping;
CSF_ShadersDirectory defines the directory for GLSL programs (required for 3D viewer to work);
CSF_UnitsDefinition and CSF_UnitsLexicon should define paths to resource files Lexi_Expr.dat and Units.dat, respectively (required for support of measurement units);
CSF_SHMessage defines the path to the messages file for ShapeHealing;
CSF_XSMessage defines the path to the messages file for STEP and IGES translators;
CSF_StandardDefaults, CSF_StandardLiteDefaults*, **CSF_XCAFDefaults, and CSF_PluginDefaults define paths to directory where configuration files for OCAF persistence are located (required for open/save operations with OCAF documents);
CSF_IGESDefaults and CSF_STEPDefaults (optional) define paths to directory where resource files of IGES and STEP translators are located;
CSF_XmlOcafResource is required in order to set the path to XSD resources, which defines XML grammar.
CSF_MIGRATION_TYPES is required in order to read documents that contain old data types, such as TDataStd_Shape;
Good Coding Practices in Unity
It’s not something a lot of new developers to Unity think about, but it’s still an incredibly important topic. It’s about coding practices, and it can make your life much easier.
The idea behind coding practices is that you keep in mind a set of guidelines when you write your code. These guidelines are often designed to keep your code maintainable, extensible, and readable, which in turn helps reduce the pain of refactoring.
How many times have you wanted to change some code in your project, which turned out to be much harder than you thought because there’s a bunch of classes relying on that code – it’s like when you go to unplug your keyboard, and you find that the back of your computer is a horror-inducing tangled mess of cables and there’s almost no hope of picking out just the one.
So, here’s some general guidelines to help you keep code untangled and tidy.
Single Responsibility
A given class should be, ideally, responsible for just one task.
The idea behind Single Responsibility is that each class does its own little task, and then you can solve larger goals by combining these little tasks together. If that sounds like I’m describing components, that’s because the two work perfectly together.
Unity being designed around separation of functionality into reusable parts, Single Responsibility is perhaps the most important principle of the ones I’m going to present in this post.
To give an example of this principle, let’s say we have a Player class. Player handles input, physics, weapons, health, and inventory.
That’s a rather long list of things the Player is responsible for. We should break this into multiple different components that each do just one thing.
PlayerInput – responsible for handling input
PlayerPhysics – responsible for driving physics simulation
WeaponManager – responsible for managing player weapons
Health – responsible for player health
PlayerInventory – responsible for player inventory
Ah, much better. Now, these classes are all largely dependent on each other, and that still poses some issues. Let’s take a look at resolving this.
Dependency Inversion
If a class relies on another class, abstract that reliance.
The idea behind Dependency Inversion is that whenever one class calls into another class, we should replace that call with some kind of abstraction to better insulate the classes from each other.
Most preferable is to replace the class dependence with an interface. So class A instead of calling methods in class B, actually calls methods of ISomeInterface which class B implements.
Another way is to introduce an abstract base class which class B inherits from. So class A treats class B as the base class instead of directly relying on class B itself.
The least preferable reliance, of course, is to have class A directly relying on class B. This is the one we want to avoid.
So in our previous example, those components may have a fairly tight coupling with each other. PlayerInput may rely on the presence of PlayerPhysics, WeaponManager may rely on the presence of Inventory, and so on.
Let’s abstract these.
IActorPhysics – Interface for classes which can accept input and presumably affect physics simulation
IDamageable – Interface for classes which can accept damage
IInventory – Interface for classes which can store and retrieve items
Now our PlayerPhysics implements IActorPhysics, our Health implements IDamageable, and our PlayerInventory implements IInventory.
So then PlayerInput just relies on the presence of some IActorPhysics, WeaponManager relies on the presence of some IInventory, and perhaps something which deals damage to our player relies on the presence of some IDamageable.
Dependency Inversion helps reinforce Single Responsibility to some extent. PlayerInput shouldn’t care how the player moves, nor should it care what is going to move the player. Just that there’s something which promises that functionality.
Another thing to keep in mind is that SendMessage can accomplish the same goals in some cases.
Modularization
I’ve personally seen code like this a lot in Unity:
Copy codeC#
switch( behavior )
{
case 1: // some behavior
case 2: // another behavior
case 3: // yet another behavior
case 4: // the last behavior
}
1
2
3
4
5
6
7
Sure it works, but we can do better. This code is practically screaming to be modularized. Each of those behaviors would be a module, and then “behavior” goes from being an enum or what have you to just being an instance of a module (lets say our module in this case is a delegate, although it could just as easily be a class or struct). So then that code just becomes:
Copy codeC#
behavior();
1
And somewhere else you can assign the current module like:
Copy codeC#
MyClass.behavior = someBehavior;
1
Where presumably someBehavior is a function (or, if our module is a class, an instance of that class, or whatever)
This is particularly useful if we’re making something like a state machine or a menu system. While we could have a big enum of all of the possible states, or of all of the possible menus, etc it makes a lot of sense to have state and menu be modules we can swap in and out. That way, we don’t have to keep adding new entries to the enum, and we don’t have to keep expanding our switch case statement every time we want to add something.
Conclusion
These are not by any means the only coding practices available. But, they are some very important ones to follow.
You don’t always have to follow them – sometimes, it’s just overkill and doesn’t make sense. But, do exercise critical thinking and determine whether your code could benefit from them (chances are, it can). Remember, it’s usually not about saving yourself a few lines of code now – it’s about saving yourself a headache later.
blog.theknightsofunity.com/unitytoolbag-library-overview/
The idea behind coding practices is that you keep in mind a set of guidelines when you write your code. These guidelines are often designed to keep your code maintainable, extensible, and readable, which in turn helps reduce the pain of refactoring.
How many times have you wanted to change some code in your project, which turned out to be much harder than you thought because there’s a bunch of classes relying on that code – it’s like when you go to unplug your keyboard, and you find that the back of your computer is a horror-inducing tangled mess of cables and there’s almost no hope of picking out just the one.
So, here’s some general guidelines to help you keep code untangled and tidy.
Single Responsibility
A given class should be, ideally, responsible for just one task.
The idea behind Single Responsibility is that each class does its own little task, and then you can solve larger goals by combining these little tasks together. If that sounds like I’m describing components, that’s because the two work perfectly together.
Unity being designed around separation of functionality into reusable parts, Single Responsibility is perhaps the most important principle of the ones I’m going to present in this post.
To give an example of this principle, let’s say we have a Player class. Player handles input, physics, weapons, health, and inventory.
That’s a rather long list of things the Player is responsible for. We should break this into multiple different components that each do just one thing.
PlayerInput – responsible for handling input
PlayerPhysics – responsible for driving physics simulation
WeaponManager – responsible for managing player weapons
Health – responsible for player health
PlayerInventory – responsible for player inventory
Ah, much better. Now, these classes are all largely dependent on each other, and that still poses some issues. Let’s take a look at resolving this.
Dependency Inversion
If a class relies on another class, abstract that reliance.
The idea behind Dependency Inversion is that whenever one class calls into another class, we should replace that call with some kind of abstraction to better insulate the classes from each other.
Most preferable is to replace the class dependence with an interface. So class A instead of calling methods in class B, actually calls methods of ISomeInterface which class B implements.
Another way is to introduce an abstract base class which class B inherits from. So class A treats class B as the base class instead of directly relying on class B itself.
The least preferable reliance, of course, is to have class A directly relying on class B. This is the one we want to avoid.
So in our previous example, those components may have a fairly tight coupling with each other. PlayerInput may rely on the presence of PlayerPhysics, WeaponManager may rely on the presence of Inventory, and so on.
Let’s abstract these.
IActorPhysics – Interface for classes which can accept input and presumably affect physics simulation
IDamageable – Interface for classes which can accept damage
IInventory – Interface for classes which can store and retrieve items
Now our PlayerPhysics implements IActorPhysics, our Health implements IDamageable, and our PlayerInventory implements IInventory.
So then PlayerInput just relies on the presence of some IActorPhysics, WeaponManager relies on the presence of some IInventory, and perhaps something which deals damage to our player relies on the presence of some IDamageable.
Dependency Inversion helps reinforce Single Responsibility to some extent. PlayerInput shouldn’t care how the player moves, nor should it care what is going to move the player. Just that there’s something which promises that functionality.
Another thing to keep in mind is that SendMessage can accomplish the same goals in some cases.
Modularization
I’ve personally seen code like this a lot in Unity:
Copy codeC#
switch( behavior )
{
case 1: // some behavior
case 2: // another behavior
case 3: // yet another behavior
case 4: // the last behavior
}
1
2
3
4
5
6
7
Sure it works, but we can do better. This code is practically screaming to be modularized. Each of those behaviors would be a module, and then “behavior” goes from being an enum or what have you to just being an instance of a module (lets say our module in this case is a delegate, although it could just as easily be a class or struct). So then that code just becomes:
Copy codeC#
behavior();
1
And somewhere else you can assign the current module like:
Copy codeC#
MyClass.behavior = someBehavior;
1
Where presumably someBehavior is a function (or, if our module is a class, an instance of that class, or whatever)
This is particularly useful if we’re making something like a state machine or a menu system. While we could have a big enum of all of the possible states, or of all of the possible menus, etc it makes a lot of sense to have state and menu be modules we can swap in and out. That way, we don’t have to keep adding new entries to the enum, and we don’t have to keep expanding our switch case statement every time we want to add something.
Conclusion
These are not by any means the only coding practices available. But, they are some very important ones to follow.
You don’t always have to follow them – sometimes, it’s just overkill and doesn’t make sense. But, do exercise critical thinking and determine whether your code could benefit from them (chances are, it can). Remember, it’s usually not about saving yourself a few lines of code now – it’s about saving yourself a headache later.
blog.theknightsofunity.com/unitytoolbag-library-overview/
Информация о контроле версий для Unity3D
www.youtube.com/watch?v=66mJnlka2E0
www.youtube.com/watch?v=1PfDC9lq6rE
unity3d.com/ru/learn/tutorials/topics/production/mastering-unity-project-folder-structure-version-control-systems
ru.stackoverflow.com/questions/519283/%D0%9A%D0%B0%D0%BA-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C-git-%D0%B4%D0%BB%D1%8F-%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D1%8F-%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D0%B9-%D0%B2-unity3d
www.youtube.com/watch?v=2iUin7FaBCg
www.youtube.com/watch?v=1PfDC9lq6rE
unity3d.com/ru/learn/tutorials/topics/production/mastering-unity-project-folder-structure-version-control-systems
ru.stackoverflow.com/questions/519283/%D0%9A%D0%B0%D0%BA-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C-git-%D0%B4%D0%BB%D1%8F-%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D1%8F-%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D0%B9-%D0%B2-unity3d
www.youtube.com/watch?v=2iUin7FaBCg
Extjs 6.0.2/guides/components/trees
docs.sencha.com/extjs/6.0.2/guides/components/trees.html
Trees
.
.
//ЗДЕСЬ НАДО ДОПОЛНИТЬ НЕДОСТАЮЩИЙ ТЕКСТ
.
Загрузка и сохранение через прокси
Loading and Saving via Proxy
Загрузка и сохранение данных деревьев немного более сложна так-как все данные необходимы для предоставления в древовидном виде. Далее будут описаны принципы работы с данными деревьев.
Loading and saving Tree data is somewhat more complex than dealing with flat data because of all the fields that are required to represent the hierarchical structure of the Tree. This section will explain the intricacies of working with Tree data.
NodeInterface поля
NodeInterface Fields
Первой и самой важной вещью в понимании работы с данными деревьев является понимание работы полей класса NodeInterface.
Каждый узел дерева это просто экземпляр Модели, декорированный полями и методами класса NodeInterface.
The first and most important thing to understand when working with Tree data is how the NodeInterface class' fields work. Every node in a Tree is simply a Model instance decorated with the NodeInterface's fields and methods. Assume for a moment that an application has a Model called «Person». A Person only has two fields — «id» and «name»:
,
,
,
//ЗДЕСЬ НАДО ДОПОЛНИТЬ НЕДОСТАЮЩИЙ ТЕКСТ
,
,
,
,
NodeInterface Fields are Reserved Names
It is important to note that all of the above field names should be treated as «reserved» names. For example, it is not allowed to have a field called «parentId» in a Model if that Model is intended to be used in a Tree, since the Model's field will override the NodeInterface field. The exception to this rule is when there is a legitimate need to override the persistence of a field.
Постоянные и непостоянные поля
Persistent vs Non-persistent Fields
Большинство полей NodeInterface сконфигурированы как непостоянные по умолчанию.
Most of NodeInterface's fields default to persist: false. This means they are non-persistent fields by default. Non-persistent fields will not be saved via the Proxy when calling the TreeStore's sync method or calling save() on the Model. In most cases, the majority of these fields can be left at their default persistence setting, but there are cases where it is necessary to override the persistence of some fields.
The following example demonstrates how to override the persistence of a NodeInterface field. When overriding a NodeInterface field it is important to only change the persist property. The name, type, and defaultValue properties should never be changed.
.
.
.
.
.
Загрузка данных
Loading Data
Имеется два пути загрузки данных дерева. Первый заключается в в том, чтобы настроить прокси таким образом, чтобы он загружал все узлы разом. Для больших деревьев это не самый лучший путь, возможно, будет предпочтительнее использовать второй метод — динамически загружать дочерние узлы для каждого раскрывающегося узла.
There are two ways to load Tree data. The first is to for the proxy to fetch the entire Tree all at once. For larger Trees where loading everything at once is not ideal, it may be preferable to use the second method — dynamically loading the children for each node when it is expanded.
Loading the Entire Tree
Internally, the Tree only loads data in response to a node being expanded. However the entire hierarchy can be loaded if the proxy retrieves a nested object containing the whole Tree structure. To accomplish this, initialize the TreeStore's root node to expanded:
Trees
.
.
//ЗДЕСЬ НАДО ДОПОЛНИТЬ НЕДОСТАЮЩИЙ ТЕКСТ
.
Загрузка и сохранение через прокси
Loading and Saving via Proxy
Загрузка и сохранение данных деревьев немного более сложна так-как все данные необходимы для предоставления в древовидном виде. Далее будут описаны принципы работы с данными деревьев.
Loading and saving Tree data is somewhat more complex than dealing with flat data because of all the fields that are required to represent the hierarchical structure of the Tree. This section will explain the intricacies of working with Tree data.
NodeInterface поля
NodeInterface Fields
Первой и самой важной вещью в понимании работы с данными деревьев является понимание работы полей класса NodeInterface.
Каждый узел дерева это просто экземпляр Модели, декорированный полями и методами класса NodeInterface.
The first and most important thing to understand when working with Tree data is how the NodeInterface class' fields work. Every node in a Tree is simply a Model instance decorated with the NodeInterface's fields and methods. Assume for a moment that an application has a Model called «Person». A Person only has two fields — «id» and «name»:
,
,
,
//ЗДЕСЬ НАДО ДОПОЛНИТЬ НЕДОСТАЮЩИЙ ТЕКСТ
,
,
,
,
NodeInterface Fields are Reserved Names
It is important to note that all of the above field names should be treated as «reserved» names. For example, it is not allowed to have a field called «parentId» in a Model if that Model is intended to be used in a Tree, since the Model's field will override the NodeInterface field. The exception to this rule is when there is a legitimate need to override the persistence of a field.
Постоянные и непостоянные поля
Persistent vs Non-persistent Fields
Большинство полей NodeInterface сконфигурированы как непостоянные по умолчанию.
Most of NodeInterface's fields default to persist: false. This means they are non-persistent fields by default. Non-persistent fields will not be saved via the Proxy when calling the TreeStore's sync method or calling save() on the Model. In most cases, the majority of these fields can be left at their default persistence setting, but there are cases where it is necessary to override the persistence of some fields.
The following example demonstrates how to override the persistence of a NodeInterface field. When overriding a NodeInterface field it is important to only change the persist property. The name, type, and defaultValue properties should never be changed.
.
.
.
.
.
Загрузка данных
Loading Data
Имеется два пути загрузки данных дерева. Первый заключается в в том, чтобы настроить прокси таким образом, чтобы он загружал все узлы разом. Для больших деревьев это не самый лучший путь, возможно, будет предпочтительнее использовать второй метод — динамически загружать дочерние узлы для каждого раскрывающегося узла.
There are two ways to load Tree data. The first is to for the proxy to fetch the entire Tree all at once. For larger Trees where loading everything at once is not ideal, it may be preferable to use the second method — dynamically loading the children for each node when it is expanded.
Loading the Entire Tree
Internally, the Tree only loads data in response to a node being expanded. However the entire hierarchy can be loaded if the proxy retrieves a nested object containing the whole Tree structure. To accomplish this, initialize the TreeStore's root node to expanded:
How to Build an simple Opencascade Program using Visual C++
milindasf.blogspot.ru/2014/03/how-to-build-simple-opencascade-program.html
neweopencascade.wordpress.com/2014/03/18/how-to-create-an-opencascade-project-using-qt/
www.opencascade.com/content/build-new-project
quaoar.su/blog/page/open-cascade-technology-chast-2-ustanovka
quaoar.su/blog/page/ustanovka-open-cascade-technology-7
neweopencascade.wordpress.com/2014/03/18/how-to-create-an-opencascade-project-using-qt/
www.opencascade.com/content/build-new-project
quaoar.su/blog/page/open-cascade-technology-chast-2-ustanovka
quaoar.su/blog/page/ustanovka-open-cascade-technology-7