c# pdf viewer open source : How to change page order in pdf acrobat SDK Library API .net asp.net windows sharepoint World%20of%20Warcraft%20Programming%20(2nd%20Edition)136-part1802

Appendix A
Best Practices 1319
function RecycleTable(t)
for key in pairs(t) do
t[key] = nil
end
table.insert(freeTables, t)
end
Whenever you want a new table, you call
GetTable
.This function attempts
toremove a recycledtablefrom
freeTables
.A new one will be createdfor you
if
freeTables
isempty.Onceyou’re donewith the table,youcall
RecycleTable
to empty it and place it back into
freeTables
.
The major disadvantage of table recycling is that it puts you, the pro-
grammer, back in charge of handling memory allocation and de-allocation,
essentially taking on the role of garbage collector. In fact, some programmers
believe this completely defeats the purpose of using a garbage-collected lan-
guage in the first place. However,in time-critical tasks where youneed to use
(and discard) many small tables, the performance gains cannot be ignored.
It is up to you to strike the appropriate balance between performance and
clarity.
Other Fine-tuning Optimizations
Thenextfewtipsofferslightperformanceimprovementsforvarioussituations.
For the most part, Lua is fast enough to let you organize your addon’s logic
as intuitively as possible. However, there may be times when you need to
squeeze out every last ounce of CPU power.
Check Expected Conditions First
When Lua processes a chain of
if
...
elseif
statements, it goes through one
by one until it finds a condition that evaluates to true—or it runs into the
end
.If the chain is long enough and executed frequently, careful ordering can
providea substantial speedimprovement.Mostofthetimewhencreating such
statements,youwill have some idea of which conditions are most likely. Take
advantage of this foreknowledge to place the most likely conditions earlier in
the chain, as in the following pseudo-code:
if likely condition then
do stuff
elseif less likely condition then
do other stuff
elseif equally likely condition then
do yet some more stuff
elseif unlikely condition then
more stuff goes here
end
How to change page order in pdf acrobat - re-order PDF pages in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Support Customizing Page Order of PDF Document in C# Project
pdf reorder pages online; how to reverse pages in pdf
How to change page order in pdf acrobat - VB.NET PDF Page Move Library: re-order PDF pages in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Sort PDF Document Pages Using VB.NET Demo Code
how to move pages around in pdf; move pages in pdf online
1320 Part V
Appendixes
Even if you do not know beforehand what conditions will be most likely,
some simple profiling tests can help figure that out for you. For instance,
you could maintain counters for each clause that increment whenever they
execute. Then you could create a function to print out the stats. Most of the
time, such optimization is unnecessary. If you’re doing anything in
OnUpdate
or some other extremely frequent code path, though, it may just be worth the
research. (Remember to remove said counters for the release version of your
mod because incrementing them has its own performance impact.)
Exploit Shortcut Evaluation
In a similar vein, you can use a feature of Lua (and other programming
languages) called shortcut evaluation to optimize the conditionals themselves.
Consider the expression
a or b
.The
or
operator evaluates to true if either
a
or
b
evaluates to
true
.Once Lua knows that
a
is true, there is no reason to
evaluate
b
.Similarly, as soon as it’s known that
c
is false in the expression
c and d
,the entire expression is known to be false.
This also has the interesting benefit (in Lua) that every non-nil, non-false
value is considered true. Then you can initialize in the following way:
variable = variable or “Some default string“
to accomplish something equivalent to the following:
if not variable then
variable = “Some default string“
end
Depending on your specific need, you may find the Boolean expression
easier to read.
In addition, any time you have a complex condition with several clauses,
you should try to put the most likely and/or fastest-to-evaluate clauses first.
In pseudo-code, this would look something like the following:
if likely condition or less likely condition then
do stuff
elseif fast condition and slow condition then
do stuff
end
NOTE
This section describes the logical result of the evaluation of Boolean
expressions. As discussed in Chapter 2, the actual results of the and and or
operators are one of the two operands depending on whether the first one is
interpreted as true (anything other than false or nil)—the
return table.remove(freeTables) or {} statement from the earlier
GetTable function, for example.
.NET PDF Document Viewing, Annotation, Conversion & Processing
Convert image files to PDF. File & Page Process. Re-order, rotate PDF pages. PDF Read. Print. Support for all the print modes in Acrobat PDF.
rearrange pdf pages online; reorder pdf pages reader
VB.NET PDF: How to Create Watermark on PDF Document within
create a watermark to PDF file in order to help or image (such as business's logo) on any desired PDF page. And with our PDF Watermark Creator, users need no
move pages in pdf document; change page order pdf
Appendix A
Best Practices 1321
Use Tables as a Logic Structure
Sometimes you will have a long chain of
if
...
elseif
where each clause
compares the same variable to some constant. The prime example in addon
programming is an
OnEvent
script. Consider the following:
if event == “SOME_EVENT“ then
-- do stuff
elseif event == “ANOTHER_EVENT“ then
-- do stuff
elseif event == “THIRD_EVENT“ then
-- do stuff
elseif event == “FOURTH_EVENT“ then
-- do stuff
end
You can use a table in a manner similar to the ‘‘Rework Repetitive Code’’
section earlier in this appendix. Instead of the
if
statement, you fill a table
with functions indexed by the name of the event:
local eventHandlers = {
[“SOME_EVENT“] = function(frame, namedArgument)
-- do stuff
end,
[“ANOTHER_EVENT“] = function(frame, namedArgument1, namedArgument2)
-- do stuff
end,
[“THIRD_EVENT“] = function(frame)
-- do stuff
end,
[“FOURTH_EVENT“] = function()
-- do stuff
end
}
Now the
OnEvent
script can be simplified to four lines (or one if you are
careful about what events you register):
function MyEventHandler(frame, event, ...)
local handler = eventHandlers[event]
if handler then
handler(frame, ...)
end
end
This technique affords a few advantages:
The underlying architecture of the table lookup usually executes more
quickly than a string of
if
...
elseif
clauses, especially with a large
number of entries.
GIF to PDF Converter | Convert GIF to PDF, Convert PDF to GIF
as easy as printing; Support both single-page and batch Drop image to process GIF to PDF image conversion; Provide filter option to change brightness, color and
change pdf page order online; move pages in a pdf file
JPEG to PDF Converter | Convert JPEG to PDF, Convert PDF to JPEG
It can be used standalone. JPEG to PDF Converter is able to convert image files to PDF directly without the software Adobe Acrobat Reader for conversion.
how to change page order in pdf document; pdf move pages
1322 Part V
Appendixes
Each event handler is a separate entity. Defining separate functions for
each one adds a level of context that can make the code easier to follow.
Parameters can be adjusted to suit the event. As demonstrated in the
preceding example, you can give names to the individual elements of
...
that would normally be accessed via
select
or by creating new local
variables in each
if
/
elseif
clause. You can even eliminate parameters
altogether if they are irrelevant to the given event.
As with the textures example earlier, you can use the table keys for the
actual registering and unregistering of the events:
for event in pairs(eventHandlers) do
someFrame:RegisterEvent(event)
end
Cache Frequently Accessed Values
There are many situations where you use a function to generate or retrieve a
value basedsolelyon agivenparameter.Forinstance, the slash commandhan-
dling system scans through the
SlashCmdList
table’s indexes, and then looks
for corresponding global variables. Ifthe variable matches the slash command
you used, WoW executes the associated function from
SlashCmdList
.
With the potential for dozens of unique functions each with several equiva-
lent slash commands (for example,
/t
,
/w
,
/tell
,and
/whisper
), the amount
of processing necessary to select the appropriate function is substantial (take
a look at
ChatEdit_ParseText
in
FrameXML\ChatFrame.lua
to see what we
mean). WoW solves this problem by storing the results of each unique com-
mand search in a table called
hash_SlashCmdList
.When you use a slash
command, it first looks to see if it’s in the list. If so, it immediately uses the
associated function. Otherwise, it goes through the more involved process.
You can create an easy-to-use caching systemwith a simple metatable trick.
From the point of view of the code using the cache, it behaves as a simple
table. For example:
print(cacheTable[entry])
You make
cacheTable
into a cache with code like the following:
cacheTable = setmetatable({}, {
__index = function (table, parameter)
local value = DoStuff(parameter)
rawset(table, parameter, value)
return value
end
})
Now whenever you provide an entry that doesn’t exist, a new entry will be
created with the result of
DoStuff(parameter)
.
PDF to WORD Converter | Convert PDF to Word, Convert Word to PDF
PDF to Word Converter has accurate output, and PDF to Word Converter doesn't need the support of Adobe Acrobat & Microsoft Word.
how to reorder pages in a pdf document; reorder pages in pdf online
TIFF to PDF Converter | Convert TIFF to PDF, Convert PDF to TIFF
doesn't require other third-party such as Adobe Acrobat. a few clicks; Ability to convert PDF documents to and upgrade; Easy to convert multi-page PDF files to
rearrange pdf pages reader; how to rearrange pages in a pdf document
Appendix A
Best Practices 1323
The WoW Environment
Thelast part of this appendix deals specificallywith constructs andprocedures
unique to World of Warcraft.
Use What You’re Given
By now, it should be second nature to look for APIs and widget methods to
help with your day-to-day tasks. However, many other built-in features go
neglected.For instance, authors often write their own functions to convert the
returns from
UnitName
into
“name“
or
“name-realm“
to indicate cross-realm
players. Granted, this is a rather trivial task, but WoW already provides such
afunction called
GetUnitName
at the end of
FrameXML\UnitFrame.lua
.
Obviously, we do not expect you to familiarize yourself with the entirety
of FrameXML code as you’re starting out, but it is always a good idea to
look in files that may be related to your addon, both to see how things are
done in the default UI and to find functions to take advantage of yourself. For
example, if you are writing an alternative quest frame, you should look over
QuestFrame.lua
and
QuestFrame.xml
before you begin work on your addon.
GetBagItemCount
from the beginning of this appendix could actually be
improved slightly. Rather than
for bag = 0, 4 do
, where
4
is a prime
example of a magic number, you can define a constant for the number
of bags. However, Blizzard has saved you the trouble. Near the top of
FrameXML\ContainerFrame.lua
is the constant
NUM_BAG_FRAMES
,which repre-
sents the number of bags besides the backpack. Using the Blizzard-defined
constant adds a bit of future-proofing to your code. If they ever increase the
numberofbags a playercan carry,theywill bump
NUM_BAG_FRAMES
to the new
count and your function will be instantly compatible.
Localize with Global Strings
Virtually every display string in the UI is stored in a constant in
FrameXML\
GlobalStrings.lua
.This file is translated to every language WoW supports.
By using the constants in this file for various aspects of your addon, you will
be automatically localizing certain parts of it, which is of great benefit to your
international users.
Error messages, button text, combat log strings, and many others are there
forthetaking.Manycommon termssuchas‘‘Yes,’’‘‘No,’’and‘‘Okay,’’areeasy
enough to recognize. You will also see strings for the various races, genders,
classes, and other commonly used terms. Whenever you are looking into
localization for your addon, open
GlobalStrings.lua
and do a preliminary
search for the terms you want.
Even ifyoudonotseethe exactphrase you’relookingfor,thesearchmaystill
help.Ifyouare trying to do localization yourself, youmaybe abletofigure out
DICOM to PDF Converter | Convert DICOM to PDF, Convert PDF to
Adobe Acrobat or any other print drivers when they use DICOM to PDF Converter. Additionally, high-quality image conversion of DICOM & PDF files in single page
change pdf page order reader; pdf reverse page order
BMP to PDF Converter | Convert Bitmap to PDF, Convert PDF to BMP
interface; Powerful image converter for Bitmap and PDF files; No need for Adobe Acrobat Reader & print driver during conversion; Support
move pages in pdf; how to move pages in pdf files
1324 Part V
Appendixes
the basic structure of the phrase in the target language but not how some par-
ticular termtranslates.You can find
GlobalStrings.lua
from other locales on
some addon sites and compare the phrases to come up with the missing term.
Avoid Deprecated Systems
The World of Warcraft UI code has gone through many evolutionary and
revolutionary changes as new needs for the game and from the addon com-
munity have come to light. New systems are constantly being added and
tweaked to take better advantage of Lua design patterns, improve efficiency,
and implement new game features.
Unfortunately, the time invested in the older systems is significant enough
that many of them are still around in some form or another. Through the
patch cycle, though, the default UI is being slowly reworked to use the newer
methods and, atsome pointin time,the old ways may no longerbe supported.
Throughout this book we have purposefully omitted coverage of these past
practices. If you use the code for the default UI or other addons as research
material for your own addon, translate any usage of the constructs discussed
in the following sections into the newer method.
NOTE
Rather than listing all deprecated systems in this section, specific events,
APIs, and so forth that should no longer be used are marked as deprecated in their
reference entries (see Part IV).
Global Widget Handler Arguments
The widget handler system you saw in Chapter 12 is new as of patch 2.0.
Instead of calling your handler with a
self
parameter and other related data
(
button
for
OnClick
,
event
and
...
for
OnEvent
,and so on), the old system
useda global variable called
this
and several global argumentvariables(
arg1
,
arg2
,and so on).
There were a few problems with this approach. Using global variables for a
parameterized systemdoes notmake muchsense conceptually,nottomention
their impact on performance. Also, the generic
argn
variables go against the
very first pointer in this appendix. The only way for you to know the meaning
of the argument when reading old code is to look at a reference for the given
handler or hope you can infer its meaning from what the code does with it.
Following are two somewhat useless functions to illustrate the difference.
If you use
SetScript
to assign them to an
OnHyperlinkClick
script, they will
function identically.
function MyAddon_OnHyperlinkClick()
if arg3 == “LeftButton“ then
this.link = arg1
print(“You clicked on “..arg2)
end
end
Appendix A
Best Practices 1325
function MyAddon_OnHyperlinkClick(self, link, text, button)
if button == “LeftButton“ then
self.link = link
print(“You clicked on “..text)
end
end
As you can see,
this
corresponds to
self
,
arg1
corresponds to
link
,
arg2
corresponds to
text
,and
arg3
corresponds to
button
.With the exception of
the
OnEvent
handler,
this
and
arg1
-
argn
will always match the parameter list
of the given handler. In this way, you can use the widget handler reference
in Chapter 31 to determine the meanings of the global arguments in any
legacy code. The only difference with
OnEvent
is that
event
always had its
own global.
arg1
-
argn
, in this case, correspond to the parameters passed
through
...
.
bag and slot Attributes on item Type Action Buttons
Another change in 2.1 is the simplification of secure action buttons with a
“type“
attribute of
“item“
. Previously, the
“item“
attribute could only be
used to activate an item by name. To use an item in your inventory would
require a
“slot“
attribute; to use an item in your bags required
“bag“
and
“slot“
attributes. Now the
“item“
attribute works the same way as the
/use
macro command. It accepts an itemname, item ID (in the form
“item:12345“
),
slot number, or bag and slot numbers separated by a space (for example,
“3 12“
).
Again, for backward compatibility, the
“bag“
and
“slot“
attributes are
still supported. However, you should no longer use them; as a comment in
FrameXML\SecureTemplates.lua
says, ‘‘Backward compatibility code, depre-
cated but still handled for now.’’ [Emphasis mine.]
Avoiding Common Mistakes
Addon authors can make dozens of common mistakes as they develop their
addons. Many of them have been covered throughout the book, but the
following deserve to be mentioned here, as well.
Adding Files While WoW Is Running
When World of Warcraft loads, it scans the file system and builds a table of
files that can be loaded during that session. If you add files while the game is
open, they won’t be part of that table and cannot be loaded or recognized by
the game. A related common mistake is adding a new file to your addon and
the Table of Contents file without fully exiting the game.
If you add files to the file system, make sure that you fully exit and restart
the game so that the changes will be fully registered.
1326 Part V
Appendixes
Entering | into the Chat Edit Box
Because World of Warcraft uses the
|
character in its color codes and
hyperlinks, any that are entered in the edit box are automatically escaped
to a double
||
.This can be problematic when running Lua scripts with the
/script
and
/run
commands. You can substitute thesequence
\124
instead of
the actual character to get around this limitation.
‘‘Missing’’ Frames
When youcreate a frame in youraddon youexpectit tobe visible. If you can’t
find your frame, it may be missing due to not meeting one of the following
requirements:
Theframemusthave some visualcomponent,such asa texture,backdrop,
or text element.
Theframemustnotbe set ashidden in theXMLfile,orthe frame’s
Show()
method must have been called to explicitly show the frame.
Each frame that is aparentofthe frame must alsobeshown.Thisincludes
the frame’s parent, the parent’s parent, and so on.
The frame mustbe anchoredsomewhere within the bounds ofthe screen.
It’s easy to spend time digging through your code only to find later that
you’ve forgotten to place the frame on the screen.
Ignoring Logs\FrameXML.log
When working on XML,therearetwoplaces tocheck to ensure thefileis being
parsed and validatedproperly:
Loadthefileinsomeprogramthatcanindicatethatthe fileis well-formed.
This could include most web browsers or a more complex XML edi-
tor/validator.
Check the
Logs\FrameXML.log
file to ensure there weren’t any errors
parsing the file.
Not Checking API Returns
There are times when the Blizzard API functions may return something
other than what you’d expect. For example, there’s a small period of time
where
UnitClass(unit)
can return
nil
when you’d expect a class name to be
returned. If you use these function returns in some othercomputation, such as
indexing a table or calling another function, you may get an error somewhere
along the line.
Appendix A
Best Practices 1327
In many cases, you can fix the problem by supplying default values in the
following way or by throwing an explicit error with the
error()
function:
local class = UnitClass(unit) or “Warrior“
Even if the class is wrong, you can be sure you won’t have an unexpected
error.
Requesting Data Before PLAYER_LOGIN
As stated in the earlier chapters, a number of functions don’t return the
correct results until the
PLAYER_LOGIN
event has fired. This can be remedied
by delaying the call until that point, but you should be aware when getting
unexpected results that the information may not be available in the client at
that moment.
Conflicting or Existing Anchor Points
Each frame can have multiple anchor points that help define the place-
ment or size of the frame. When adjusting anchor points, make certain that
you’ve cleared any that should no longer be set. When in doubt, run the
ClearAllPoints()
method to ensure that a frame has no anchors before
adding your own anchor points.
Documents you may be interested
Documents you may be interested