In college courses, I have never been clear about analog circuits until now. I always think the circuit diagram is very strange. I always ask "what is this part of the circuit used?" and "why is this effect ". In my mind, each part of the circuit should be useful, but I always do not understand. My mom said that my idea has been fixed by the software for too long. I should not always look at the circuit diagram by modules. The correct method should be from the power supply to the circuit, the other pole of the power supply is always seen. I still don't understand the circuit diagram, but I do. Code In terms of experience, I think Analysis Source code According to this idea, it is easier to clarify the context.
In sharpdevelop code, due to a lot of interfaces and plug-ins, many codes suddenly lose the clue of function/method calls when they see somewhere. For example, when you look at the implementation of a function, it will jump to an interface, because this part of the function will be executed for an object that implements this interface at runtime. From this perspective, the design pattern also makes it a little difficult for us to study the code. This problem often occurs when you look at the source code in Linux. A better way to look for code clues is to use a text search tool to search for related keywords. In Linux, I often use grep. In Windows, the "batch file search" function similar to ultraedit can be very useful (or tools such as "search and replace ). This is a little bit of my experience reading code. If you know a better method, please let me know how to learn it? .
I don't want to post code for a large segment (space, bandwidth, and the attention of the audience). I will post the main code as needed, therefore, it is best to look for the code. Decompress the code package and I have resolved it to "F: \ sharpdevelop" (if not described, the following is the root directory of the Code ). Sharpdevelop itself is not very convenient for viewing the code, and there is no function such as "go to definition". Therefore, I suggest you convert its code into a vs project. Unfortunately, the Project Export function of sharpdevelop is faulty. If \ SRC \ sharpdevelop is exported. the general composite project CMBX will fail (I remember that the RC1 version was successful, but I don't know why it went wrong in later versions), so I can only export the project one by one.
Okay. Let's take a look at the sharpdevelop code.
1. Start Point
In the master Program The starting point is \ SRC \ main \ Startup \ sharpdevelopmain. cs. Find the main function, which is the starting point of the entire program. The start part is to display the cover form and add command line control. The splashscreenform is defined in \ SRC \ main \ base \ GUI \ dialogs \ splashscreen. in the CS file, I will not talk about this part. Which is
Application. threadexception + = New Threadexceptioneventhandler (showerrorbox );
Sharpdevelop controls exceptions to effectively report errors. When the system encounters an exception, sharpdevelop intercepts it and pops up its own exception prompt report dialog box. This code is implemented in this line. The showerrorbox method is in the sharpdevelopmain class, And the exceptionbox is defined in \ SRC \ main \ Startup \ dialogs \ exceptionbox. CS. If you need to implement exception control, you can learn the skills here.
2. Full of xuanjicang Initialization
String [] Addindirs = Icsharpcode. sharpdevelop. addinsettingshandler. getaddindirectories ( Out Ignoredefaultpath );
Addintreesingleton. setaddindirectories (addindirs, ignoredefaultpath );
Use addinsettingshandler to get the directory of the plug-in and notify addintreesingleton. Addinsettingshandler is defined in \ SRC \ main \ Startup \ dialogs \ addintreesettingshandler. CS, it reads the system configuration (App. the path attribute of the addindirectory node in the file to determine the directory location of the plug-in, or you can specify the Directory through the addindirectories section you have defined. If you do not configure these settings, the default directory is under the .. \ addins directory of the sharpdevelop running directory.
Servicemanager. Services. addservice ( New Messageservice ());
Servicemanager. Services. addservice ( New Resourceservice ());
Servicemanager. Services. addservice ( New Iconservice ());
You can use servicemanager to add three default services, namely message service, Resource Service, and Icon service. Among the three services, messageservice displays various information prompts, and the other two are system resources. sharpdevelop performs unified calling and management through services.
Servicemanager. Services. initializeservicessubsystem ("/workspace/services ");
Initialize other services. Sharpdevelop defines services in the/workspace/services path of the plug-in tree. All plug-ins under this path are considered as services. Therefore, if you define a service by yourself, you also need to attach it to this path (here is the extension point of the System Service ).
Note!In this step, we quietly carried out an important initialization work under our eyes. For more information, see servicemanager defined in the \ SRC \ main \ core \ Services \ servicemanager. CS file. Check its initializeservicessubsystem method. We found this line
Addservices (iservice [])
Addintreesingleton. addintree . Gettreenode (servicespath). buildchilditems (this). toarray (typeof (iservice )));
Here, addintreesingleton calls the addintree instance for the first time. In Singleton mode, the instance is initialized only when the instance is called for the first time. The addintree of the entire system is initialized in this step. We will introduce in detail how to initialize addintree later. Let's take a look at service initialization first. In the initializeservicessubsystem method of servicemanager, you can use addintree to retrieve all configurations under the service plug-in path, read and create specific objects, and add them to the service list. Call the initializeservice method of each service one by one to initialize the service.
Let's take a look at the initialization work of addintree later. We will first read the main body code.
Commands = addintreesingleton. addintree. gettreenode ("/workspace/autostart"). buildchilditems (null );
For(IntI = 0; I <commands. Count-1; ++ I)
{
(Icommand) commands [I]). Run ();
}
/Workspace/autostart is the extension path of the system's automatic run command. The plug-in defined in this path will automatically run when the system starts. Here, the command (command) in this path is initialized through the plug-in tree and executed one by one. The buildchilditems method is used to create the command list under this extension point. I will describe its implementation when introducing addtree.
At the end of the main program code, initialize and close the cover form, and then execute the last command (that is, the main interface of the system) in the command list ). When the main interface exits, the system detaches all services.
In this part of the code, we know the extension path/workspace/services and/workspace/autostart specified by the two systems, when we implement the service and specify the system to automatically run commands, We can mount these two extension point paths.
Servicemanager. Services can use the type (Interface) to find a specific instance, that is, the getservices method. However, the specific implementation of servicemanager can be viewed later. This is not the most important part.
Next, let's take a look at the core-addintree code of the entire plug-in system and see how it initializes and establishes the backbone of the plug-in tree of the entire system through plug-in configuration.